java中的 toString()方法实例代码
前言:
toString()方法相信大家都用到过,一般用于以字符串的形式返回对象的相关数据。
最近项目中需要对一个ArrayList
处理要求把集合数据转换成字符串形式,格式为:子集合1数据+"#"+子集合2数据+"#"+....+子集合n数据。
举例:集合数据:[[1,2,3],[2,3,5]] 要求转成为"[1,2,3]#[2,3,5]"形式的字符串
第一次是这样处理的:
ArrayList>a=newArrayList<>();//打造这样一个数据的集合[[1,2],[2,3]]要求生成字符串[1,2]#[2,3] for(inti=0;i<2;i++){ ArrayList
然后看该处理下的Log日志:
05-1210:29:18.4859565-9565/com.xxx.aaaI/myinfo:[1,2]
05-1210:29:18.4859565-9565/com.xxx.aaaI/myinfo:[2,3]
05-1210:29:18.4959565-9565/com.xxx.aaaI/myinfo:[1,2]#[2,3]
我们会发现我们想要的是[1,2]#[2,3]形式的字符串,但是结果是[1,2]#[2,3] ,在第二个值开始往后,前面都多了一个空格。
接下来我们查看集合下的.toString()方法的源码:
翻译一下官方解释:
1、返回这个Collection类(Set和List的父类)的字符串表现形式
2、这个表现形式有一个规定的格式,被矩形括号"[]"包含
3、里面的子元素被“,”(逗号和空格)分割(这是重点)
/**
*Returnsthestringrepresentationofthis{@codeCollection}.Thepresentation
*hasaspecificformat.Itisenclosedbysquarebrackets("[]").Elements
*areseparatedby','(commaandspace).
*
*@returnthestringrepresentationofthis{@codeCollection}.
*/
@Override
publicStringtoString(){
if(isEmpty()){
return"[]";
}
StringBuilderbuffer=newStringBuilder(size()*16);
buffer.append('[');
Iterator>it=iterator();
while(it.hasNext()){
Objectnext=it.next();
if(next!=this){
buffer.append(next);
}else{
buffer.append("(thisCollection)");
}
if(it.hasNext()){
buffer.append(",");
}
}
buffer.append(']');
returnbuffer.toString();
}
分析这个Collection下的.toString()方法源码,分为几个部分:
1、判断集合是不是空(empty),即集合内有没有数据。如果是空值(没有数据)的话,直接返回字符串"[]"
2、如果集合不是空值,说明有数据
①、迭代取下一个子元素(Objectnext=it.next()),如果这个子元素是集合本身,添加"(thisCollection)"到StringBuffer类的buffer对象中
②、如果这个子元素不是集合本身,添加到buffer对象中
③、如果这个子元素下面还有子元素,则添加","到buffer对象中去,用于分割两个相邻子元素
3、返回StringBuffer.toString()字符串
由此可见,返回[1,2]#[2,3]是官方正确的返回形式,那么对于这个问题,其实在改不了源码的情况下给得到的字符串后面使用.replaceAll("","");把字符串中的空格都去掉
注意:源码中有一段代码:
if(next!=this){
buffer.append(next);
}else{
buffer.append("(thisCollection)");
}
这里可能有些同学看不懂,这里举个例子,还是上面的那个,我们在子集合里面添加代码c.add(c);将集合本身添加到集合中去,看看打印结果
ArrayList>a=newArrayList<>(); for(inti=0;i<2;i++){ ArrayList
看日志结果中红色部分,是不是看懂了,如果集合中的子元素是集合本身,就将"(thisCollection)"添加到返回集合中
05-1210:58:00.6158424-8424/com.maiji.magkarepatientI/myinfo:[1,2,(thisCollection)]
05-1210:58:00.6158424-8424/com.maiji.magkarepatientI/myinfo:[2,3,(thisCollection)]
至此,上面这个问题解决了,下面我们看下其他类下的.toString()源码。
一、Object
/** *Returnsastringcontainingaconcise,human-readabledescriptionofthis *object.Subclassesareencouragedtooverridethismethodandprovidean *implementationthattakesintoaccounttheobject'stypeanddata.The *defaultimplementationisequivalenttothefollowingexpression: **getClass().getName()+'@'+Integer.toHexString(hashCode())*See
Writingauseful *{@codetoString}method *ifyouintendimplementingyourown{@codetoString}method. * *@returnaprintablerepresentationofthisobject. */ publicStringtoString(){ returngetClass().getName()+'@'+Integer.toHexString(hashCode()); }
翻译一下官方解释:
1、返回一个对于这个Object简明的、可读的的字符串
2、Object类的子类被鼓励去重写这个方法来提供一个实现用于描述对象的类型和数据
3、默认的执行形式和下面这个例子一致
getClass().getName()+'@'+Integer.toHexString(hashCode())
综上:当你的一个类中没有重写.toString()方法的时候就会执行根类Object的这个.toString()方法。
返回形式:对象的类名+@+哈希值的16进制
getClass().getName()返回对象所属类的类名 hashCode()返回该对象的哈希值 Integer.toHexString(hashCode())将对象的哈希值用16进制表示
举例:
Objectd=newObject();
Log.i("myinfo",d.toString());
05-1211:23:00.75817406-17406/com.maiji.magkarepatientI/myinfo:java.lang.Object@e23e786
二、String,StringBuilder,StringBuffer
三个都是字符串的表现形式,但是有区别的
①、String.toString() ,直接返回本身
/**
*Returnsthisstring.
*/
@Override
publicStringtoString(){
returnthis;
}
②、StringBuilder
官方解释:以字符串的形式返回这个builder对象的内容
/**
*Returnsthecontentsofthisbuilder.
*
*@returnthestringrepresentationofthedatainthisbuilder.
*/
@Override
publicStringtoString(){
/*Note:Thismethodisrequiredtoworkaroundacompilerbug
*intheRIjavac(atleastin1.5.0_06)thatwillgeneratea
*referencetothenon-publicAbstractStringBuilderifwedon't
*overrideithere.
*/
returnsuper.toString();
}
追溯到super.toString()实现
/**
*ReturnsthecurrentStringrepresentation.
*
*@returnaStringcontainingthecharactersinthisinstance.
*/
@Override
publicStringtoString(){
if(count==0){
return"";
}
returnStringFactory.newStringFromChars(0,count,value);
}
③、StringBuffer
@Override
publicsynchronizedStringtoString(){
returnsuper.toString();
}
追溯到super.toString()
/**
*ReturnsthecurrentStringrepresentation.
*
*@returnaStringcontainingthecharactersinthisinstance.
*/
@Override
publicStringtoString(){
if(count==0){
return"";
}
returnStringFactory.newStringFromChars(0,count,value);
}
综上我们发现,StringBuffer和StringBuilder最终都调用了父级 “AbstractStringBuilder”中的toString()方法
但是他们本身的toString()却有所不同,我们由此可以总结
1、StringBuilder:线程非安全的
StringBuffer:线程安全的
2、StringBuilder处理速度要比StringBudiler快的多
3、单线程大量数据操作,用StringBuilder ,因为StringBuilder速度快,因为单线程所以不考虑安全性
多线程大量数据操作,用StringBuffer , 因为StringBuffer安全
三、Map
先看源码:
可以看到返回的形式是{key1=value1,key2=value2}
注意 1、当Map集合中没有数据的时候返回{}
2、每两个数据之前用","分割,和Collection一致,一个逗号、一个空格
3、当键值是集合本身的时候,添加 (thisMap)
publicStringtoString(){
Iterator>i=entrySet().iterator();
if(!i.hasNext())
return"{}";
StringBuildersb=newStringBuilder();
sb.append('{');
for(;;){
Entrye=i.next();
Kkey=e.getKey();
Vvalue=e.getValue();
sb.append(key==this?"(thisMap)":key);
sb.append('=');
sb.append(value==this?"(thisMap)":value);
if(!i.hasNext())
returnsb.append('}').toString();
sb.append(',').append('');
}
}
举例:
Mapmap=newHashMap<>(); map.put("keyA","valueA"); map.put("keyB","valueB"); map.put("keyC","valueC"); Log.i("myinfo",map.toString());
打印结果:
05-1211:41:30.8984490-4490/com.maiji.magkarepatientI/myinfo:{keyA=valueA,keyB=valueB,keyC=valueC}
以上所述是小编给大家介绍的java中的toString()方法实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!