• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
茨翁米英人
博客园    首页    新随笔    联系   管理    订阅  订阅
Day09JAVA常用类

String

String是字符串,使用一对""引起来表示

  1. String声明为final的,不可被继承

  2. String实现了Serializable接口:表示字符串是支持序列化的

  3. String实现了Comparable接口:表示String可以比较大小

  4. String内部定义了final char[] value 用于存储字符串数据

  5. String:代表不可变的字符序列。简称不可变性,不可在原有的字符串位置上进行赋值

  6. 通过字面量的方式(区别于new)给一个字符串赋值,此时字符串声明在常量池中

String s1 = "abc";//字面量的定义方式
-----------------------------------------
System.out.println(s1 == s2);//比较s1和s2的地址值

7.字符串常量池中不会存储相同内容的字符串

体现:

  • 当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的valu进行赋值

  • 当对现有字符串进行连接操作,也需要重新指定内存区域重新赋值,不能在原有的value上赋值

  • 当调用String的replace()方法时,也需要重新指定内存区域重新赋值,不能在原有的value上赋值

String对象的创建

String str = "hello";
​
//本质上this.value = new char[0];
String s1 = new String();
​
//本质上this.value = original.value;
String s2 = new String(Stirng original);
​
//本质上this.value = Arrays.copeOf(value,value.length);
String s3 = new String(char[] a);
String s4 = new String(char[] a,int starIndex,int count);

String的实例化方式

//通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区的字符串常量池中
String s1 = "javaEE";
String s2 = "javaEE";
//通过new + 构造器的方式:此时s3和s4保存的地址值,是数据在堆空间开辟空间对应的地址值,但value属性的地址与javaEE字符串常量池中的地址相同
String s3 = new String("javaEE");
String s4 = new String("javaEE");
​
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//flase
System.out.println(s1 == s4);//flase
System.out.println(s3 == s4);//flase

面试题:

String s = new String("abc");方式创建对象,在内存中创建了几个对象?

答:两个。一个是堆空间new结构,另一个是char[]对应的常量池数据"abc"。

String不同拼接操作的对比

结论:

  • 常量与常量的拼接结果在常量池,且常量池不会存在相同内容的常量

  • 只要其中有一个是变量,结果的地址就在堆中

  • 如果拼接的结果调用intern()方法,返回值就在常量池中

一道面试题

public class StringTest{
   String str = new String("good");//*****String具有不可变性
   char[] ch = {'t','e','s','t'};
   
   public void change(String str,char cha[]){
       str = "test ok";
       ch[0] = 'b';
  }
   
   public static void main(String[] args){
       StringTest ex = new StringTest();
       ex.change(ex.str,ex.ch);
       System.out.println(ex.str);//good
       System.out.println(ex.ch);//best
  }
}

String,StringBuffer,StringBuilder三者的异同?

  • String:不可变的字符序列;底层使用char[]存储

  • StringBuffer:可变的字符序列;线程安全,效率低;底层使用char[]存储

  • StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全,效率高;底层使用char[]存储(一般多线程情况下使用)

源码分析

String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char value = new char[]{'a','b','c'};
​
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度是16的数组
System.out.println(sb1.length());
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
​
StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length+16];
​
//问题一 System.out.println(sb2.length());//3
//问题二 扩容问题:如果要添加的数据底层数组盛不了,那就需要扩容底层的数组。默认情况下,扩容为原来容量的2倍+2,同时将原有的数组的元素复制到另一个数组

String常用方法1

- int length();//返回字符串长度:return value.length
- char charAt(int index);//返回某索引处的字符 return value[index]
- boolean isEmpty();//判断是否是空字符串 return value.length == 0;
- String toLowerCase();//使用默认环境语言,将String中所有字符转换成小写
- String toUpperCase();//使用默认环境语言,将String中所有字符转换成大写
- String trim();//返回字符串的副本,忽略前导空白和尾部空白
- boolean equal(Object obj);//比较字符串内容是否相同
- boolean equalIgnoreCase(String anotherString);//比较字符串内容是否相同,忽略大小写
- String concat(String str);//将指定字符串连接到此字符串结尾,等价于“+”
- int compareTo(String anotherString);//比较两个字符串大小
- String substring(int beginIndex);//返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后一个子字符串
- String substring(int beginIndex,int endIndex);返回一个新的字符串,它是此字符串的从beginIndex开始截取到endindex(不包括)的一个子字符串

 

posted on 2021-03-07 22:56  茨翁米英人  阅读(54)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3