`
he_wen
  • 浏览: 234032 次
  • 性别: 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>

相关推荐

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例078 从字符串中分离文件路径、 文件名及扩展名 98 实例079 判断手机号的合法性 99 实例080 用字符串构建器追加字符 100 实例081 去掉字符串中的所有空格 101 实例082 汉字与区位码的转换 102 第5章 面向对象技术...

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

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

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    JAVA面试题最全集

    写一个方法,实现字符串的反转,如:输入abc,输出cba 写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出bbbhhtccc。 3.数据类型之间的转换 如何将数值型字符转换为数字(Integer,Double) 如何将数字...

    java面试题

    答:String是不可变的对象,每次对String类型进行改变都相当于产生了一个新的对象,StringBuffer是可变的字符序列,所以如果要经常改变某个字符串的话建议使用StringBuffer。 list、set、map问题? 答:set 不允许...

    net学习笔记及其他代码应用

    答:string str = null 是不给他分配内存空间,而string str = \"\" 给它分配长度为空字符串的内存空间。 25.请详述在dotnet中类(class)与结构(struct)的异同? 答:Class可以被实例化,属于引用类型,是分配在内存的...

    jQuery权威指南-源代码

    不仅书中的每一个小知识点都配有精心选择的小案例(总共100多个),而且还有两个非常实用的综合性案例。所有案例的讲解都非常详细,不仅有功能需求分析和完整实现代码,而且还有最终效果的展示,更重要的是,将所有...

    C++ Primer中文版(第5版)李普曼 等著 pdf 1/3

     11.3.6 一个单词转换的map 391  11.4 无序容器 394  小结 397  术语表 397  第12章 动态内存 399  12.1 动态内存与智能指针 400  12.1.1 shared_ptr类 400  12.1.2 直接管理内存 407  12.1.3 shared_ptr和...

    C++Primer(第5版 )中文版(美)李普曼等著.part2.rar

     11.3.6 一个单词转换的map 391  11.4 无序容器 394  小结 397  术语表 397  第12章 动态内存 399  12.1 动态内存与智能指针 400  12.1.1 shared_ptr类 400  12.1.2 直接管理内存 407  12.1.3 shared_ptr和...

Global site tag (gtag.js) - Google Analytics