`
he_wen
  • 浏览: 238747 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

高效率分离字符串到一个Map中

    博客分类:
  • Java
 
阅读更多
package test.hewen;

import java.io.UnsupportedEncodingException;
import java.util.Map;

public class StringUtil {
	/***
	 * 把一个字符串分离开,并按照key/value形式保存到Map中
	 * @param map 字符串中的字符存放在map中
	 * @param data 要分离的字符串
	 * @param encoding 字符编码
	 * @throws UnsupportedEncodingException
	 */
	public static void parseParameters(Map map, String data, String encoding)
			throws UnsupportedEncodingException {

		if ((data != null) && (data.length() > 0)) {//将字符串转换为字节数组
			byte[] bytes ;
			bytes=data.getBytes();
			parseParameters(map, bytes, encoding);
		}

	}

	/****
	 * 将字节数组中的字符分离到map中,该方法支持字符分离的标记:'%',
	 * '?','&'
	 * 
	 * @param map 存放分离的字符
	 * @param data  分离的字节数组
	 * @param encoding 按什么编码方法
	 * @throws UnsupportedEncodingException
	 */
	public static void parseParameters(Map map, byte[] data, String encoding)
			throws UnsupportedEncodingException {

		if (data != null && data.length > 0) {
			int ix = 0;
			int ox = 0;
			String key = null;
			String value = null;
			while (ix < data.length) {//对分离的字符数组循环
				byte c = data[ix++];
				switch ((char) c) {
				case '%':
				case '?':
				case '&'://当字节数组中的元素,遇到'%','?','&'字符,就创建value字符串
					value = new String(data, 0, ox, encoding);
					if (key != null) {
						putMapEntry(map, key, value);
						key = null;
					}
					ox = 0;
					break;
				case '='://当字节数组中的元素,遇到'='字符,那么创建key字符串
					key = new String(data, 0, ox, encoding);
					ox = 0;
					break;
				case '+'://当字节数组中的元素,遇到'+',那么就是以' '代替
					data[ox++] = (byte) ' ';
					break;
				default:
					data[ox++] = c;
				}
			}
			//最后一个截取的字符串,要进行处理
			if (key != null) {
				value = new String(data, 0, ox, encoding);
				putMapEntry(map, key, value);
			}
		}
	}
	
	/****
	 * 把分离的小字符串存放在map中
	 * 
	 * @param map
	 * @param name
	 * @param value
	 */
	private static void putMapEntry(Map map, String name, String value) {
		map.put(name, value);
	}

}

 

测试类:

 

package test.hewen;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

/****
 * 这个是把一个字符串分离开,并按照key/value形式保存到Map中,
 * 分离的格式是以%,?,&其他就不支持了
 * 
 * @author Administrator
 *
 */

public class Test {

	public static void main(String[] args) throws UnsupportedEncodingException {
		String encoding = "ISO-8859-1";
		String queryString="userName=tar+zan%password=pw+d";
		Map.Entry entry;
		 Map results= new HashMap();
		StringUtil.parseParameters(results, queryString, encoding);
		Iterator it=results.entrySet().iterator();
		while(it.hasNext()){
			 entry=(Entry) it.next();
			 System.out.println("key="+entry.getKey()+" value="+entry.getValue());
		}
	}

	
}
分享到:
评论
30 楼 mhsjlove 2013-07-08  
正则表达式的捕获组比这好用多了
29 楼 風一樣的男子 2010-12-10  
String key = null; 
            String value = null;

貌似这么初始化字符串不是好习惯吧?
28 楼 he_wen 2010-12-10  
不是以讹传讹是互相讨论,讨论了才映像深刻,才能够有进步。。。
27 楼 mercyblitz 2010-12-10  
<div class="quote_title">既然这么热的话,我也来点评一下把!<br>
</div>
<div class="quote_title"><br></div>
<div class="quote_title">hardPass 写道</div>
<div class="quote_div">
<div class="quote_title"><span style="font-weight: normal;"><strong><span style="font-weight: normal;">
<pre name="code" class="java"><span style="white-space: normal;"><span style="white-space: pre;">
</span></span></pre>
</span></strong></span></div>
<p> </p>
<p> </p>
<p>int len = data.length();</p>
<p><span style="white-space: pre;"> </span>byte[] bytes = new byte[len];</p>
<p><span style="white-space: pre;"> </span>bytes=data.getBytes();</p>
<p> </p>
<p> </p>
</div>
<p> </p>
<p>没有理解,String是字符串,不是字节串,长度一般不会相等。 char[] 和byte[]的区别!</p>
<p> </p>
<p>楼主修改后,是不是还有问题呢?</p>
<p> </p>
<pre name="code" class="java">package test.hewen;

import java.io.UnsupportedEncodingException;
import java.util.Map;

public class StringUtil {

public static void parseParameters(Map map, String data, String encoding)
throws UnsupportedEncodingException {

if ((data != null) &amp;&amp; (data.length() &gt; 0)) {//将字符串转换为字节数组
byte[] bytes ;
bytes=data.getBytes(); //修改后,还是有问题!
parseParameters(map, bytes, encoding);
}

}
}
</pre>
 
<p><br>还是上面哪句话,字符串不是字节串,字符串是有编码的。<span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> parseParameters(Map map, </span><span class="keyword">byte</span><span>[] data, String encoding)  的实现注意了字符</span></span></p>
<p> </p>
<p>比如:</p>
<p> </p>
<pre name="code" class="java"> key = new String(data, 0, ox, encoding);  </pre>
<p> 。</p>
<p> </p>
<p>为什么<span> </span><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> parseParameters(Map map, String data, String encoding)  没有注意呢?</span></span></p>
<p> </p>
<p>楼主是不是忽略了java.lang.String#getBytes(String encoding)的方法呢?</p>
<p> </p>
<p> </p>
<p>请楼主谦虚点:</p>
<p>he_wen 写道</p>
<div class="quote_title">
<div class="quote_div">哥们,那个搞错了,大家多注意下,我贴出来的意思也是让大家多多学习。。。 </div>
</div>
<div class="quote_title"><br></div>
<div class="quote_title">  he_wen 写道</div>
<div class="quote_div">哥们不要重构而重构,思维固化了可不是什么好事。在重构里面讲的只是建议。。。 </div>
<p> </p>
<p>请原谅我比较直接,自己没有搞明白的时候,不要以讹传讹。不要去研究什么Tomcat实现,先打好基础!</p>
<p> </p>
<p> </p>
26 楼 mercyblitz 2010-12-10  
hardPass 写道
luckaway 写道
hardPass 写道
悠游键客 写道
为啥要传一个Map参数进去,而不是直接就返回一个Map对象呢?


这个问题,难道也要问吗?

Map做为参数传递的好处应该很明显的……

啥好处?



我首先想到的两个好处是:
1、具体的Map类型可以由调用者控制,比如有的人希望是HashMap,有的希望是LockedMap……

2、可能不是新建的Map,原来Map里就有数据.
比如,我这边要解析1个报文,报文里有多行。每行都需要解析,所有行的解析的结果都是放在同一个Map里,这只是个例子。




1.用返回的方法也是一样的,多态而已!

2.不利于测试!
25 楼 tq02ksu 2010-12-10  
为啥不用正则表达式. 那代码读起来多舒服.

其实正则表达式也不舒服. 一个人写的别人也看着费劲.
不过至少比这一大段代码维护起来要容易.
24 楼 butteryrose 2010-12-10  
发现中文;号了,不知道测试过没,楼主
23 楼 dsjt 2010-12-10  
luckaway 写道
hardPass 写道
luckaway 写道
hardPass 写道
悠游键客 写道
为啥要传一个Map参数进去,而不是直接就返回一个Map对象呢?


这个问题,难道也要问吗?

Map做为参数传递的好处应该很明显的……

啥好处?



我首先想到的两个好处是:
1、具体的Map类型可以由调用者控制,比如有的人希望是HashMap,有的希望是LockedMap……

2、可能不是新建的Map,原来Map里就有数据.
比如,我这边要解析1个报文,报文里有多行。每行都需要解析,所有行的解析的结果都是放在同一个Map里,这只是个例子。

1.用哪个具体类,一般都是由由被调用者决定的,对调用者而言应该是透明的。但是也不能排除你所提到这种特殊情况,
至少楼主的帖子没这个需求。


2.如果Map里面已经有数据了,你无法知道方法里会对已有的Map做哪些操作,它很有可能会覆盖原先已经有的值。
我更倾向于,return;putAll!你可能会顾及性能问题,如果你真的在乎性能,有其他更有意义的事情等你去做。

但是如果代码片断每天执行好几千亿次,可能这点性能也是较可观的,那时候可能也不会用java了!



第二条,如果“无法知道方法里会对已有的Map做哪些操作”,还调用这方法干嘛?
22 楼 luckaway 2010-12-10  
hardPass 写道
luckaway 写道
hardPass 写道
悠游键客 写道
为啥要传一个Map参数进去,而不是直接就返回一个Map对象呢?


这个问题,难道也要问吗?

Map做为参数传递的好处应该很明显的……

啥好处?



我首先想到的两个好处是:
1、具体的Map类型可以由调用者控制,比如有的人希望是HashMap,有的希望是LockedMap……

2、可能不是新建的Map,原来Map里就有数据.
比如,我这边要解析1个报文,报文里有多行。每行都需要解析,所有行的解析的结果都是放在同一个Map里,这只是个例子。

1.用哪个具体类,一般都是由由被调用者决定的,对调用者而言应该是透明的。但是也不能排除你所提到这种特殊情况,
至少楼主的帖子没这个需求。


2.如果Map里面已经有数据了,你无法知道方法里会对已有的Map做哪些操作,它很有可能会覆盖原先已经有的值。
我更倾向于,return;putAll!你可能会顾及性能问题,如果你真的在乎性能,有其他更有意义的事情等你去做。

但是如果代码片断每天执行好几千亿次,可能这点性能也是较可观的,那时候可能也不会用java了!
21 楼 hardPass 2010-12-10  
luckaway 写道
hardPass 写道
悠游键客 写道
为啥要传一个Map参数进去,而不是直接就返回一个Map对象呢?


这个问题,难道也要问吗?

Map做为参数传递的好处应该很明显的……

啥好处?



我首先想到的两个好处是:
1、具体的Map类型可以由调用者控制,比如有的人希望是HashMap,有的希望是LockedMap……

2、可能不是新建的Map,原来Map里就有数据.
比如,我这边要解析1个报文,报文里有多行。每行都需要解析,所有行的解析的结果都是放在同一个Map里,这只是个例子。


20 楼 walkintojava 2010-12-10  
有则改之,无则加勉
19 楼 borland 2010-12-10  
a=K%20F%b=ok.这个不行吧
18 楼 cantellow 2010-12-10  
luckaway 写道
he_wen 写道
哥们不要重构而重构,思维固化了可不是什么好事。在重构里面讲的只是建议。。。

好的建议

这个,我只能说,没理解到重构的精髓,重构不是优化!!!
17 楼 he_wen 2010-12-10  
谢谢你的建议
16 楼 luckaway 2010-12-10  
         Map results=null; 
             if (results == null) 
                 results = new HashMap(); 

这段啥意思?
15 楼 he_wen 2010-12-10  
其实上面这个截取的代码可以不段的扩展,里面的switch循环适当的修改可以应对很多项目的需求。。。其实本来想把这个方法抽取出来,搞个策略模式什么的,不知道大家有什么意见。。。
14 楼 luckaway 2010-12-10  
hardPass 写道
悠游键客 写道
为啥要传一个Map参数进去,而不是直接就返回一个Map对象呢?


这个问题,难道也要问吗?

Map做为参数传递的好处应该很明显的……

啥好处?
13 楼 luckaway 2010-12-10  
he_wen 写道
哥们不要重构而重构,思维固化了可不是什么好事。在重构里面讲的只是建议。。。

好的建议
12 楼 he_wen 2010-12-10  
哥们,那个搞错了,大家多注意下,我贴出来的意思也是让大家多多学习。。。
11 楼 hardPass 2010-12-10  
<div class="quote_title"><span style="font-weight: normal;"><strong><span style="font-weight: normal;">
<pre name="code" class="java"><span style="white-space: normal;"><span style="white-space: pre;">
</span></span></pre>
</span></strong></span></div>
<p> </p>
<p> </p>
<p>int len = data.length();</p>
<p><span style="white-space: pre;"> </span>byte[] bytes = new byte[len];</p>
<p><span style="white-space: pre;"> </span>bytes=data.getBytes();</p>
<p> </p>
<p> </p>
<p> </p>
<p>不错,楼主最近好像在读TOMCAT代码,支持楼主贴出好代码,顺便也让我们懒人也一同提高提高。</p>
<p>这种方法不错,正好最近有个报文头解析的需求,可以参考一下这个方法。</p>
<p> </p>
<p>不过,请解释下那个 <span style="color: #ff0000; white-space: pre;"><span style="color: #000000;"><strong>new byte[len]</strong></span>有啥用?</span></p>

相关推荐

    一个使用JSON-lib和json2.js的示例

    JSON-lib是Java中处理JSON的一个库,它提供了多种方式将Java对象转换为JSON格式的字符串,同时也可以将JSON格式的字符串转换回Java对象。JSON-lib支持多种Java对象类型,包括基本类型、集合、数组、Map以及自定义...

    nim-templates:Nim的简单字符串模板库

    nim-templates库是专为Nim语言设计的一个轻量级字符串模板引擎,它允许开发者以一种声明式的方式处理字符串,生成动态内容,常用于Web开发中的HTML渲染或生成静态文本。 nim-templates库的核心概念是模板,模板是一...

    JakartaCommons 详细教程更助于你的基础

    这一系列组件为Java开发人员提供了一个强大的工具库,能够简化日常开发任务并提高效率。 1. Jakarta Commons Lang Jakarta Commons Lang库提供了一系列用于字符串处理、基本对象操作、数学计算和时间操作的工具。它...

    石家庄天远科技集团有限公司—Java开发笔试题

    `public`成员在任何地方都可访问,`private`成员只能在定义它们的类内部访问,而`protected`成员在同一个包或子类中可访问。 `String`、`StringBuffer`和`StringBuilder`都是用来处理字符串的类,但它们有不同的...

    fastjson-1.1.2

    1. **高性能**:Fastjson以其高效的性能著称,无论是解析JSON字符串还是生成JSON字符串,都能达到较高的速度,远超同类JSON库。 2. **易用性**:API设计简洁明了,开发者可以轻松上手,进行JSON操作。 3. **自动...

    实现FreeMark读取模板生成HTML

    3. **构建数据模型**: 在Java代码中,你需要创建一个数据模型(通常是一个Map对象),将要显示的数据绑定到对应的键上。例如,你可以创建一个Map,其中键是“name”,值是你要显示的名字。 ```java Map, Object&gt; ...

    String Template API.chm

    而“工具”标签则表明,StringTemplate是一个实用的辅助工具,可以帮助开发者提高开发效率,生成高质量的文本输出。 在实际应用中,StringTemplate常用于生成报表、邮件模板、配置文件等场合。由于其强大的功能和...

    java 面试题

    这些类型直接存储在内存中,而`String`类则是引用类型,它在Java中是一个对象,存储在堆内存中。`String`类提供了丰富的字符串处理方法,如拼接、查找、替换等。 #### 2. 字符串操作详解 字符串的反转和替换可以...

    1000道 互联网Java工程师面试题 485页 .pdf

    在MyBatis中,#{ }和${ }是两种不同的参数传递方式,#{ }用于传递参数,而${ }用于传递字符串。 在MyBatis中,可以使用like语句来进行模糊查询,例如: `SELECT * FROM users WHERE name LIKE '%${name}%'` 在...

    C++API中文帮助文档

    7. 字符串:std::string是C++中的一个类,用于处理文本数据。它提供了许多操作字符串的方法,如拼接(+运算符)、查找、替换等。 8. 数值计算:C++标准库还包含了一些数学函数,如sqrt(平方根)、pow(幂运算)、...

    200多个js技巧代码

    9. **闭包**:闭包是JavaScript中的一个高级特性,它允许函数访问并操作其外部作用域的变量,常用于创建私有变量和实现模块化。 10. **错误处理**:try...catch语句用于捕获和处理运行时错误,是编写健壮代码的关键...

    设计模式_java语言中的应用

    Java的字符串池就是一个享元模式的实例,通过`String.intern()`方法可以实现。 11. 模板方法模式(Template Method Pattern):定义一个操作中的算法骨架,而将一些步骤延迟到子类中。在Java的`java.io.InputStream...

    Python必会的12道面试题.pdf

    - 三引号的另一个常见用途是作为类或模块的文档字符串,可以通过 `__doc__` 属性访问: ```python class MyClass: """这是一个类的例子.""" print(MyClass.__doc__) ``` #### 2. Python的参数传递,是值...

    超级有影响力霸气的Java面试题大全文档

    当客户机第一次调用一个Stateful Session Bean 时,容器必须立即在服务器中创建一个新的Bean实例,并关联到客户机上,以后此客户机调用Stateful Session Bean 的方法时容器会把调用分派到与此客户机相关联的Bean实例...

    JAVA相关面试题,Spring面试题

    - **Memcached**: Memcached是一个高性能、分布式内存对象缓存系统,用于加速动态Web应用,减轻数据库负载。 #### 十九、Oracle数据库中rownum与rowid的区别? - **rownum**: rownum是一个伪列,用于返回结果集中...

    单词词频统计

    2. **字符串操作**:在C++中,`std::string`类是处理字符串的基础。单词的提取通常涉及`std::getline()`函数来读取一行,然后使用`std::istringstream`或`std::stringstream`来拆分单词。为了去除标点符号,可以使用...

    MyBatis框架的应用

    在Java开发中,MyBatis是一个广泛使用的持久层框架,它将SQL语句与代码分离,提高了开发效率和可维护性。本主题主要探讨MyBatis中的动态SQL元素,包括、、、、、和,这些都是构建灵活、可扩展SQL查询的重要工具。 1...

Global site tag (gtag.js) - Google Analytics