起始
从零开始学的时候,就觉得java是从字符串开始慢慢有难度,慢慢延伸开,慢慢变得难的。
这是因为java的各种存储方式可以相互转换,而且字符串是可以唯一一个保持强转之前精度的存储格式。所以它可以根据不同的需要,保存,读取。而保存和读取的方法实际上一般都是拆分和组合的方法。所以它非常重要,也是一个基本功。
组装
字符串的组装就是对于需要存储的信息的存储。这个很简单,只要把相应的信息强转成字符串,然后按照约定的方式组合起来就可以了。
强转成String
那么,把信息强转成字符串格式又要怎么做。这个方法很多,比如说
1.所有类型都可通过加上””来变成字符串,这个道理很简单,java不同存储格式的字段相互运算的时候,java为了尽可能的不丢失精度,会把自动把精度比较低的类型强制转换成为精度比较高的存储格式。但是这种方式并不推荐,因为它其实是等于定义了两个String的对象,然后才强制转换类型,为了生成新的对象还会再新建一个String对象,一共生成了三个String对象,只是写着会方便一点而已,多了一些不必要的浪费。
2.Java有封装和自动装箱的方式,每一个存储格式都有它相应的类,类中都有强制转化的方法,String也不例外。它的方法是String.valueOf(),这个方法可以强转所有基本类型,甚至是类(当然必须写toString()方法,因为这个方法会调用toString())。
组装起来
按照约定的方法组装嘛,就看你自己的需要了,其实一般组装的约定是为了拆分和分析的方便来的。
其实所谓组装,只是简单的字符串拼接,这也有两种方法
1.还是用String的格式存储对象,简单的把需要组装的字符用“+”号连接,自然就可以拼接在一起了。但是要注意的是,因为String是定长的,所以每添加一次,就需要新建一个String的对象,这样会造成大量的资源浪费。
2.使用StringBulider,StringBulider是一个可以变长的String对象(其实是空间溢出的时候才会新建新的对象),所以会大大减少新建对象的开销。使用它组合字符串的时候只需要调用它的append()方法就可以了。
3.使用StringBuffer,它和前面的StringBulider比较相似,只是它是线程安全的,因为线程安全,就多了一些操作,操作效率就会变得低一点。但是如果可能会有线程安全的问题,就需要使用这个方法。
解析
组装起来的对象是为了存储,存储信息肯定是需要在某个条件下使用的,那么就必须要存储好的String信息一步步还原成组装之前的有用的信息。
这个步奏其实是组装的逆操作,反着回来就可以了。把字符串拆分,然后根据约定去把数据强制转回所需要的类型(有时需要做一些类型检验)。
拆分
这一步的方法必须依赖组装的步奏。所以这里的所有东西都是依赖在组装的时候符合相应的约定的前提下的。
字符串的拆分有很多种方法
1.String中的toCharArray()方法,这个方法返回一个char数组,把String的每一个字符都转换成char格式放入这个数组中,数组的下标就是这个字符在String中出现的位置。这个方法的好处是不浪费空间(任何一个字符都有作用),又非常简单(只需一个方法就可以了)。但是这个方法也有几个很大的缺陷:每条信息的存储格式大小有限(一个字符),当然也可以有方法组装成几个字符但是需要比较繁琐的操作,不如用其他方法;信息强转成其他格式会遇到一些比较棘手的问题(char转成其他格式会变成字符相应的ASCII编码格式相应的数字)。
2.String中的split()方法 ,这个方法需要在不同的信息中间加入相应的分隔符,然后这个方法分割的时候会返回一个分割之后的String数组。这个方法需要花费一些开销(组装的时候需要添加分隔符),但是可以灵活多变(可以添加不同的分隔符,不同层次的分割),有待开发,特别是应对复杂对象转成String格式存储的时候,可以不同层次用不同的约定(但也加大了拆分错误的可能性)。这是推荐使用的方法,它对字符的个数没有限制,对不信息的格式也没有任何要求,又灵活多变,所需开销可以自己想办法减少。这个方法中,技术操作远远不及约定重要,好的约定可以完成很多技术操作完不成的东西。
3.依赖String中的正则表达式来拆分,这个方法的技巧更多,灵活度也更大,因为正则表达式是可以表达一切信息的格式,可以解决任何问题。而且这种方法和第二个方法并不矛盾,可以交叉使用,互为补充。但是需要对正则表达式的理解比较充分,对正则表达式的相应符号的关系和不同要明确区分。否则差值毫米,谬之千里。这个方法能应对的问题最广最深,但是需要对正则表达式理解必须充分。况且,一般需要存储成String格式的信息可能比较复杂,而且可能可变性要求高,正则表达式虽然都能表示,但是对于不同情况的兼容需要比较多的代码去协调。这是一个比较复杂的问题,用第二个方法的话只需要很好的约定就可以,所以不太推荐。(正则表达式会限定死格式,并行的正则表达式可以突破这个限定,但是需要过多的代码)
信息的解读
仅仅是拆分信息远远不够,还要强转会原来的格式。这个其实很简单,每个基本对象都有它相应的封装类,这个封装类里面会有相应的强行转化的方法。
int对应的封装类是Integer,相应的方法是Integer.parseInt()
char一般是用数组去存储信息,可以用new String(char数组名)去生成String对象。
byte也是一般是用数组去存储信息,可以用new String(byte数组名)去生成String对象。
boolean有它的toString()方法,但是真的需要存储boolean的信息的,可以约定成其他存储方式,比如int的0表示false,1表示true。
double和float都有valueOf()方法(Float.valueOf()和Double.valueOf()),通过它可以强制转化成自己的类型。
如果是数组的话,需要转化之后遍历赋值,如果是类的话,可以使用相应的构造方法去初始化。
这样的话,就可以将信息通过字符串的方式去存储,然后在需要的时候拿出来拆分,解读了。