java 关于字符串对象 think in java_Think in Java ---Chapter 13 字符串

String 对象是不可变的,JDK中String类的方法都是创建一个全新的String对象,即使是修改串的方法。可以用 == 运算观察一下。 String参数传递也是传递的引用的复制。

String不可变是源于这么一种思想:参数传递给方法是提供方法的信息的,而不是让方法改变参数的。

任何指向String对象的引用都不可能改变他的值,因此引用之间就互不影响。但是不可变得特性会有效率问题。例如String仅有的两个重载操作符 + 和 += 。他们可以让String和各种类型的连接(基本类型会装箱,然后和引用型一样调用toString())。使用JDK自带的反编译工具javap -c 反编译后会发现String的+运算符实际上 使用了StringBuilder类完成可能的多个参数append()方法(一个参数调用一次),然后使用toString() 生成String对象。

Java不允许重载操作符。

切记不要在循环中使用String的+或+= 方法,因为在每次循环中都会新建StringBuilder对象,append后toString 。而应该在循环外new一个StringBuilder对象。 。 sb.append(a + ":" + b); 也会让编译器掉入陷阱。

因此,对字符串的任何拼接,都应该拆成对StringBuilder对象的单独参数的append操作。

对编译器的的源码优化最好使用javap -c查看 。就能知道怎么写性能好了。

StringBuilder对字符串修改有丰富的方法,如insert, replace, substring,reverse,append,toString,delete。

与StringBuffer相比,StringBuilder是线程不安全的,但是是可变字符串操作的首选工具类。

Java中的所有类根本上都是继承Object类,所以都有toString方法。容器类也是,而且容器类也复写了toString方法。例如ArrayList.toString方法会遍历成员逐个调用toString()方法。

若希望toString打印出对象的内存地址,可以使用this关键字。例如:

public class c{

public String toString(){

// SHOULD BE super.toString()

return "Class c address:" + this + "\n";

}

public static void main(String args[]){

List v = new ArrayList();

for(int i = 0 ; i < 10; i ++){ v.add(new c()); }

System.out.println(v);

}

}

但是上面的 "Class c address:" + this + "\n" 会出现异常,因为编译器会先生成一个StringBuilder,然后append进每一个参数,当遇到 this 时,调用他的toString方法,于是发生了递归调用。

所以,这就是因为多态造成的结果。所以要调用Object.toString()方法即可,即将 this 改成 super.toString()。

C语言中使用printf可以打印栈上的内容。

熟记String的常用方法。

System.out.format() 和 System.out.printf() 方法是一样的。

Formatter类的使用:

构造他的对象需要一个OutputStream、File或者PrintStream对象。然后就可以用format方法输出了。

Formatter f = new Formatter(System.out);

f.format("%s %d", "asd",2);

再复习一下printf的格式化规则。

%[参数索引$][标志][宽度][.精确度]格式字母

标志是例如 - ,表示左对齐方向。

精确度用在String类型上表示打印的长度。不能用在整形上。

String.format() 方法类似C中的sprintf, 其内部使用了Formatter类。

Java中的正则比别的语言要多加一个'',例如 r‘\d’ 表示数字。 换行和制表符之类的还是原样。

相关方法:

String对象.matches(正则式) //进行正则测试

String对象.split(正则式) //按照正则式将字符串切分返回字符串数组

String对象.replaceFirst(正则式) //

String对象.replaceAll(正则式) //

java.util.regex 包中的Pattern类是正则类,(别的编程语言都是叫Regex)。

其中,Pattern对象主要是用来对正则字符串进行编译或其他操作的类,还可以对字符串进行使用正则的切分。

Matcher类包含有大量的匹配查询或者匹配替换等操作。

String regstr = "(.+?)\\w\\s";

Pattern p = Pattern.compile(regstr, Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE); // 忽略大小写。元字符'.'匹配行终结符。开启多行查找,即元字符'^'和'$'匹配行头和行尾,平时这两个元字符匹配完整串的开始和结束。

Matcher m = p.matcher("asddcdedd");

while(m.find()){

System.out.println("find " + m.group(0) + m.start() );

}

其中,Matcher对象的group(int gronum)和其他语言的正则类似,0表示全部匹配式,其他正数是分组号。start(int gronum)和end(int gronum)也类似。

将JDK文档中正则类加入搜藏随时查询。

正则复习: ?放在量词后表示非贪婪模式。放在元素后表示{1,}。

\W \D \S 这种一般大写的表示非...。比如\w表示单词, \W表示非单词,即空白符。

Scanner的构造器可以接受任何类型的输入对象,包括File对象,InputStream,String字符串或者实现了Readable接口的类对象!!!。然后,就可以使用Scanner对象的nextXX()系列的方法将来自于各种输入源的流进行方便的读取。下面是各种读取的效果代码:

Scanner s = new Scanner("TRUE asd 213");

s.useDelimiter(" ");

System.out.println(s.nextBoolean());

System.out.println(s.next());

System.out.println(s.nextInt());

File path = new File("test1.txt");

//BufferedWriter fw = new BufferedWriter(new FileWriter(path));

//fw.write("this.is.a.test.line");

//fw.flush();

//fw.close();

//s = new Scanner(path);

//s.useDelimiter("\\.");

//while(s.hasNext()){

//System.out.println(s.next());

//}

FileOutputStream fos = new FileOutputStream(path);

FileChannel fw = fos.getChannel();

ByteBuffer bb = ByteBuffer.allocate(256);

//bb.put(ByteBuffer.wrap("this.is.a.test.line".getBytes()));

CharBuffer cb_view = bb.asCharBuffer();

cb_view.put("this.is.a.test.line");

fw.write(bb);

fw.close();

fos.close();

s = new Scanner(path);

while(s.hasNext()){

System.out.println(s.next());

}

//Output:

//true

//asd

//213

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值