一、String类概述

1.String对象一旦创建就不能改变。

2.字符串常量池。

字符串常量池的特点:池中有则直接使用,池中没有则创建新的字符串常量。

例1: “==”  比较两个对象是否引用同一实例

  1. public class StringDemo
  2. {
  3. public static void main(String args[])
  4. {
  5. StringDemo1();
  6.  
  7. }
  8. public static void StringDemo1()
  9. {
  10. String str1="abcd";
  11. String str2="abcd";
  12. System.out.println(str1==str2);
  13. }
  14. }

以上的代码运行结果为true。

原因分析:当运行到代码String str1="abcd";处,JAVA虚拟机会先检查字符串常量池中是有相同的字符串,如果有,则返回该对象的引用,否则,新创建一个字符串并返回该对象的引用。

运行到代码String str2="abcd";的时候,JAVA虚拟机发现字符串常量池中有相同的字符串,所以不再创建而是返回该对象的引用。

例2:

  1. public class StringDemo
  2. {
  3. public static void main(String args[])
  4. {
  5. //StringDemo1();
  6. StringDemo2();
  7.  
  8. }
  9. public static void StringDemo2()
  10. {
  11. String str1="abcd";
  12. String str2=new String("abcd");
  13. System.out.println(str1==str2);
  14. }
  15. public static void StringDemo1()
  16. {
  17. String str1="abcd";
  18. String str2="abcd";
  19. System.out.println(str1==str2);
  20. }
  21. }

上述运行结果为false。

分析:运行完代码String str1="abcd";的时候,字符串常量池中将会含有一个值为abcd的字符串;执行到代码String str2=new String("abcd");时,进行了两个动作,因为使用new方法创建字符串对象的时候,所需要的构造方法中需要一个对象来创建新对象,所以,"abcd"就是一个动作,它将会在字符串常量池中寻找相同值的对象并返回该对象的引用。但是String类的构造方法中并没有直接使用该对象,而是将该对象先转换成一个字符数组,然后将该字符数组重新组装成一个字符串对象。这个过程可以通过查看源代码获得。因此使用==比较两个对象结果为false,因为它们并不是一个对象,它们的地址值不同。

例3: equals()方法 ,比较字符串对象中的字符

  1. public class StringDemo
  2. {
  3. public static void main(String args[])
  4. {
  5. //StringDemo1();
  6. //StringDemo2();
  7. StringDemo3();
  8.  
  9. }
  10. public static void StringDemo3()
  11. {
  12. String str1="abcd";
  13. String str2=new String("abcd");
  14. System.out.println(str1.equals(str2));
  15. }
  16. public static void StringDemo2()
  17. {
  18. String str1="abcd";
  19. String str2=new String("abcd");
  20. System.out.println(str1==str2);
  21. }
  22. public static void StringDemo1()
  23. {
  24. String str1="abcd";
  25. String str2="abcd";
  26. System.out.println(str1==str2);
  27. }
  28. }

该运行结果为true。

分析:先观察源代码

  1. public boolean equals(Object anObject) {
  2. if (this == anObject) {
  3. return true;
  4. }
  5. if (anObject instanceof String) {
  6. String anotherString = (String)anObject;
  7. int n = value.length;
  8. if (n == anotherString.value.length) {
  9. char v1[] = value;
  10. char v2[] = anotherString.value;
  11. int i = 0;
  12. while (n-- != 0) {
  13. if (v1[i] != v2[i])
  14. return false;
  15. i++;
  16. }
  17. return true;
  18. }
  19. }
  20. return false;
  21. }

String类的equals方法复写了Object类的方法,因此它所接收的参数对象并不是String类型的,而是Object类型的,查看该源码,我们可以发现首先先比较两个对象的引用是否相同,如果相同,则返回true;这是合理的,毕竟如果两个对象的引用都相同,则两个对象一定是完全相同的。接下来,如果两个对象的引用不相同,则并不返回false,而是挨个比较两个字符串中的字符是否相同,如果比较完成之后完全相同,则返回true,否则返回false。我们最后得出结论,那就是该方法在String类中复写之后比较的是字符串内容是否相同,相同返回true,不同返回false。这里由于两个字符串内容相同,因此返回true。

例四:intern()方法。

  1. public class StringDemo
  2. {
  3. public static void main(String args[])
  4. {
  5. //StringDemo1();
  6. //StringDemo2();
  7. //StringDemo3();
  8. //StringDemo4();
  9. //StringDemo5();
  10. StringDemo6();
  11. }
  12. public static void StringDemo6()
  13. {
  14. String str1=new String("abcd");
  15. String str2=str1.intern();
  16. String str3="abcd";
  17. System.out.println(str1==str2);
  18. System.out.println(str2==str3);
  19. }
  20. public static void StringDemo5()
  21. {
  22. char buf[]={'A','B','C','D','E'};
  23. String str=new String(buf);
  24. System.out.println(str);
  25. }
  26. public static void StringDemo4()
  27. {
  28. byte buf[]={65,66,67,68,69};
  29. String str=new String(buf);
  30. System.out.println(str);
  31. }
  32. public static void StringDemo3()
  33. {
  34. String str1="abcd";
  35. String str2=new String("abcd");
  36. System.out.println(str1.equals(str2));
  37. }
  38. public static void StringDemo2()
  39. {
  40. String str1="abcd";
  41. String str2=new String("abcd");
  42. System.out.println(str1==str2);
  43. }
  44. public static void StringDemo1()
  45. {
  46. String str1="abcd";
  47. String str2="abcd";
  48. System.out.println(str1==str2);
  49. }
  50. }

输出结果为两行:

false

true

分析:当String对象调用intern方法时,JAVA虚拟机就会到字符串常量池中寻找字符串常量并和当前字符串内容进行比较,如果值相同,则返回该字符串常量池中的常量的引用,否则创建一个新的常量并返回该常量的引用。执行String str1=new String("abcd");的时候,字符串常量池中已经有了该常量。执行String str2=str1.intern();时,由于已经有了该常量,所以会返回该常量的引用。同理,Stirng str3="abcd";时也是如此。所以会出现这样的结果。

3.String类的构造方法。

我们经常使用String str="xxxx";的形式创建字符串对象,貌似String str=new String("xxx");的形式就没有用了,其实不然,毕竟这种方式存在即合理,很多时候使用前一种方式并不能解决问题,我们还是要使用后一种方式创建字符串,特别是在需要将其它数据类型转换成字符串类型的时候。

其它数据类型主要包括字符数组和字节数组。

3.1字节数组转换成字符串。

  1. public class StringDemo
  2. {
  3. public static void main(String args[])
  4. {
  5. //StringDemo1();
  6. //StringDemo2();
  7. //StringDemo3();
  8. StringDemo4();
  9.  
  10. }
  11. public static void StringDemo4()
  12. {
  13. byte buf[]={65,66,67,68,69};
  14. String str=new String(buf);
  15. System.out.println(str);
  16. }
  17. public static void StringDemo3()
  18. {
  19. String str1="abcd";
  20. String str2=new String("abcd");
  21. System.out.println(str1.equals(str2));
  22. }
  23. public static void StringDemo2()
  24. {
  25. String str1="abcd";
  26. String str2=new String("abcd");
  27. System.out.println(str1==str2);
  28. }
  29. public static void StringDemo1()
  30. {
  31. String str1="abcd";
  32. String str2="abcd";
  33. System.out.println(str1==str2);
  34. }
  35. }

运行结果为:ABCDE。

3.2字符数组转换成字符串。

  1. public class StringDemo
  2. {
  3. public static void main(String args[])
  4. {
  5. //StringDemo1();
  6. //StringDemo2();
  7. //StringDemo3();
  8. //StringDemo4();
  9. StringDemo5();
  10.  
  11. }
  12. public static void StringDemo5()
  13. {
  14. char buf[]={'A','B','C','D','E'};
  15. String str=new String(buf);
  16. System.out.println(str);
  17. }
  18. public static void StringDemo4()
  19. {
  20. byte buf[]={65,66,67,68,69};
  21. String str=new String(buf);
  22. System.out.println(str);
  23. }
  24. public static void StringDemo3()
  25. {
  26. String str1="abcd";
  27. String str2=new String("abcd");
  28. System.out.println(str1.equals(str2));
  29. }
  30. public static void StringDemo2()
  31. {
  32. String str1="abcd";
  33. String str2=new String("abcd");
  34. System.out.println(str1==str2);
  35. }
  36. public static void StringDemo1()
  37. {
  38. String str1="abcd";
  39. String str2="abcd";
  40. System.out.println(str1==str2);
  41. }
  42. }

输出结果:ABCDE。

3.3其它构造方法。

  1. String(byte[] bytes, int offset, int length);

  该方法将指定在offset处开始处的length长度范围内的字节转换成字符串。

  1. String(char[] value, int offset, int count);

  该方法原理和上述相同。

3.4总结

  通过使用String类的构造方法可以实现字节数组和字符数组向String类对象的转换。

二、String类功能

1.获取。

1.1获取字符串字符的个数,即字符串长度。

  1. int length();

1.2根据位置获取字符

  1. char charAt(int index);

1.3根据字符(字符串)获取在字符串中的位置

自前向后找:

  1. int indexOf(int ch);
  2.  
  3. int indexOf(int ch, int fromIndex);
  4.  
  5. int indexOf(String str);
  6.  
  7. int indexOf(String str, int fromIndex);

自后向前找:

  1. int lastIndexOf(int ch);
  2.  
  3. int lastIndexOf(int ch, int fromIndex);
  4.  
  5. int lastIndexOf(String str);
  6.  
  7. int lastIndexOf(String str, int fromIndex);

  查找的时候,应当注意不要越界,否则抛出异常。
  如果没有查找到,通常返回-1,可以根据此判断字符或者字符串是否存在。

1.4 获取字符串中的一部分字符串。或者称为字串。

  1. String substring(int beginIndex, int endIndex);

  使用方法:subString,返回String,有两个参数,一个是beginIndex,一个是endIndex,截取的到是endIndex之前的一个字符。即beginIndex到endIndex-1。

  1. String substring(int beginIndex) ;

  重载方法有subString ,只有一个参数,表示从指定的位置开始,一直到字符串结尾。

2.转换。

2.1将字符串变成几部分。如果有这个功能将返回字符串数组。字符串切割

  1. String[] split(String regex, int limit);

用法举例:

          String s="张三、李四、王五";
          String []arr=s.split(",");
如果不是,而是.,则需要特殊处理,因为.是正则表达式中的特殊字符。转义\\.

2.2将字符串变成字符数组

  1. Char[] toCharArray();

2.3将字符串变成字节数组

  1. Byte[] getBytes(String charsetName);

打碎成最小单位:字节。
用法举例:

    String s="ab你";
    byte []arr=str.getBytes();
输出的结果却是:英文字母变成数字输出,而中文则变成了两个负数。中国的gb2312码最高位都是1,所以都是负数。

2.4字符串中的大小写转换

  1. String toUpperCase();将字符串中的小写字符转换成大写。
  2.  
  3. String toLowerCase();将字符串中的大写字符转换成小写字符。

2.5将字符串中的内容进行替换

  1. String replace(char oldChar, char newChar);
  2. String replace(CharSequence target, CharSequence replacement);
  3. CharSequenceString已经实现的接口。

2.6将字符串两端的空格去掉

  1. String trim();

2.7 将字符串进行连接

  1. String concat(String str);

2.8 value()方法

    此方法为String类的静态方法,参数为各种基本数据类型,作用是将基本数据类型转换成字符串

3.判断

3.1两个字符串内容是否相同

  1. boolean equals(Object anObject);
  2. boolean equalsIgnoreCase(String anotherString)//忽略大小写进行比较,其实就是先转换成大写或者小写再进行比较。

3.2字符串中是否包含某个字符串?

  1. boolean contains(CharSequence s);
  2. 其实是用indexOf方法也可以达到相同的目的。

3.3字符串是否以指定字符开头,是否以指定字符串结尾。

  1. boolean endsWith(String suffix);
  2.  
  3. boolean startsWith(String prefix);

4.比较方法

  1. int compareTo(String anotherString);
  2.  
  3. int compareToIgnoreCase(String str) ;

按照字典序比较两个字符串。
基本数据类型使用的是比较运算符,而对象比较使用的是compareTo方法。

 

三、StringBuffer类

StringBuffer类:
        就是字符串缓冲区,是用于存储数据的容器。
数组也是存储数据的容器,它和StringBuffer的区别是什么?
  1.长度可变
  2.可以存储不同类型的数据进来。
  3.最终要转成字符串才能使用。
  4.可以对字符串进行修改。

该类的构造方法中的参数是整数的时候,指定了该缓冲区的初始容量大小;

该类的构造方法是字符串时,将会构造一个StringBuffer对象,并将其内容初始化为和该字符串相同。

StringBuffer类的功能:

1.添加。

append方法。参数是基本数据类型,只有两种不行:byte和short不行,但是有int可以代替。
初始容量为16个字符。

  1. public class StringBufferDemo
  2. {
  3. public static void main(String args[])
  4. {
  5. Demo1();
  6. }
  7. public static void Demo1()
  8. {
  9. StringBuffer sb=new StringBuffer();
  10. StringBuffer bs=sb.append(4);
  11. System.out.println(sb==bs);
  12. }
  13. }

运行结果为true。

分析:一个容器加入了一些东西以后该容器仍然是该容器,并没有变化,所以结果为true。

insert方法。该方法参数分为两部分,一部分是插入的位置,一部分是插入的内容。

  1. public class StringBufferDemo
  2. {
  3. public static void main(String args[])
  4. {
  5. //Demo1();
  6. Demo2();
  7. }
  8. public static void Demo2()
  9. {
  10. StringBuffer sb=new StringBuffer();
  11. sb.append("abba");
  12. sb.insert(2,"XXXX");
  13. System.out.println(sb);
  14. }
  15. public static void Demo1()
  16. {
  17. StringBuffer sb=new StringBuffer();
  18. StringBuffer bs=sb.append(4);
  19. System.out.println(sb==bs);
  20. }
  21. }

运行结果为:abXXXXba

2.删除。

  1. StringBuffer delete(int start, int end);

  该方法包含头不包含尾。

  1. StringBuffer deleteCharAt(int index);

  该方法删除指定位置的字符。

  使用该方法可以清空缓冲区:sb.delete(0,sb.length());

3.查找。

    和String类几乎相同。

4.修改。

  1. StringBuffer replace(int start, int end, String str);

  包含头不包含尾。该方法的参数个数和String相同,但是位置颠倒了。

  1. void setCharAt(int index, char ch);

  该方法比较特殊,并没有返回StringBuffer对象。该方法将指定位置上的字符替换为指定字符。

  1. void setLength(int newLength);

  在使用该方法时,如果设定的长度小于内容的长度,则会删除多余的部分。使用此方法可以达到清空StringBuffer对象的目的,但是不推荐使用。

  1. StringBuffer reverse();

  反转字符串

四、StringBuilder类

此类提供了一个与StringBuffer兼容的API。也就是功能用法一模一样。
这两个类有什么不同?
  StringBuffer在jdk1.0就出现了,线程安全。
  StringBuilder在jdk1.5才出现,线程不安全。

浅析StringBuffer类线程安全的原因:StringBuffer类中有append方法和delete方法,如果一个线程调用append方法,另一个线程同时调用delete方法,在不加同步锁的情况下,就会出现线程安全性问题。JDK1.0考虑的线程安全性多一点,所以加上了同步;使用同步使得线程更加安全,但是这样的好处仅仅在多线程编程中--如果是单线程,由于不会出现线程安全性问题,所以如果经常使用StringBuffer类的append方法和delete方法,就会极大的降低程序的执行效率,这是每次调用方法都必须判断锁造成的。

JDK1.5考虑到了这一点,所以将同步去掉,重新创建了一个类StringBuilder,这是考虑到程序执行效率之后的结果。

我们要知道JDK升级几乎只有三点原因:

1.简化书写

2.提高效率

3.增加安全性。

而StringBuilder类出现的目的正是为了提高效率,付出的代价就是不安全。

java ——String , StringBuffer, StringBuilder类的更多相关文章

  1. 重温java中的String,StringBuffer,StringBuilder类

    不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...

  2. Java String StringBuffer StringBuilder

    String  字符串常量存储在常量区,每次追加操作会创建新的对象: StringBuffer  字符串变量  线程安全 在堆上创建,每次追加操作在原对象上进行操作:  速度 StringBuffer ...

  3. Java之String,StringBuffer,StringBuilder类

    在 java 语言中, 用来处理字符串的的类常用的有 3 个: String.StringBuffer.StringBuilder. 它们的异同点: 1) 都是 final 类, 都不允许被继承; 2 ...

  4. 【Java基础】String StringBuffer StringBuilder

    String String是不可变的 我们都知道String不是基本数据类型,而是一个对象,并且是final类型的,不可变的.(public final class String) 查看以下代码: S ...

  5. 浅谈 Java 字符串(String, StringBuffer, StringBuilder)

    我们先要记住三者的特征: String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全) 一.定义 查看 API 会发现,String ...

  6. Java String、StringBuilder和StringBuffer

    转载: Java String.StringBuilder和StringBuffer 概览 在Android/Java开发中,用来处理字符串常用的类有3种: String.StringBuilder. ...

  7. JAVA中String和StringBuilder类的特点及使用

    转自:https://www.imooc.com/code/2202 仅做个人学习记录之用,侵删! 什么是 Java 中的字符串 在 Java 中,字符串被作为 String 类型的对象处理. Str ...

  8. java中 String StringBuffer StringBuilder的区别

    * String类是不可变类,只要对String进行修改,都会导致新的对象生成. * StringBuffer和StringBuilder都是可变类,任何对字符串的改变都不会产生新的对象. 在实际使用 ...

  9. Java学习笔记--String StringBuffer StringBuilder

    String StringBuffer StringBuilder String http://docs.oracle.com/javase/7/docs/api/ 中文: http://www.cn ...

随机推荐

  1. IDEA中如何添加jar包

    File -> Project Structure -> Libraries -> + -> jar -> 选择classes

  2. 《我在谷歌大脑见习机器学习的一年:Node.js创始人的尝试笔记》阅读笔记

    文章来源:https://www.toutiao.com/i6539751003690893828/?tt_from=weixin_moments&utm_campaign=client_sh ...

  3. MOS管

    mos工作原理:http://www.360doc.com/content/15/0930/11/28009762_502419576.shtml, 开关特性好,长用于开关电源马达驱动,CMOS相机场 ...

  4. Java基础11-数组

    1.使用数组步骤: (1)声明数组 int[] a; (2)分配空间 a=new int[5]; (3)赋值 a[0]=1;  int类型数组如果没有赋值,默认值为0,String类型数组默认为nul ...

  5. (转)轻松掌握shell编程中数组的常见用法及示例

    缘起:在老男孩进行linux培训shell编程教学中,发现不少水平不错的网友及同学对数组仍然很迷糊,下面就给大家分享下数组的用法小例子,希望能给大家一点帮助.其实SHELL的数组很简单,好用.我们学习 ...

  6. 深入学习webpack(二)

    深入学习webpack(二) 在深入学习webpack(一)中,我通过一个例子介绍了webpack的基本使用方法,下面将更为系统的学习webpack的基本概念,对于一门技术的掌握我认为系统化还是很重要 ...

  7. windows 7下安装tomcat6 web服务器

    因为项目中要使用Mondrian提供ROLAP应用,而Mondrian是运行在tomcat上的. 一. 软件获取: http://tomcat.apache.org/ 二. 安装步骤: 运行可执行程序 ...

  8. Kudu-Master的设计

    不多说,直接上干货! http://blog.csdn.net/lookqlp/article/details/70858466

  9. WebGL 踩坑系列-2

    需求:绘制斑点在球面上走过的路径 思路:要绘制斑点在球面上走过的路径,首先要记录上一时刻和当前时刻该斑点所在球面的位置,并且实时更新当前时刻的斑点位置和上一时刻的斑点位置. 为了方便,上一时刻斑点所在 ...

  10. 学习JVM-GC原理

    1. 前言 Java和C++之间显著的一个区别就是对内存的管理.和C++把内存管理的权利赋予给开发人员的方式不同,Java拥有一套自动的内存回收系统(Garbage Collection,GC)简称G ...