11_String

ctrl + shift + f:查看某个类
ctrl + F12:查看所有函数名

String概述

String的本质:字符数组

字符串的构造方法

    1. 空字符串
    1. byte[] -----> String重要
    1. char[] -----> String重要
  //空字符串 ""  
  public String()  
      
  /*
  	跟字节数组相关的
  */

  //利用字节数组,创建字节数组所表示的字符串
  // 1. 字符 -> 数值形式  'a' -> 97
  // 2. 所以可以用多个字节值,表示多个字符——>即字符序列 public
  String(byte[] bytes)

  //利用字节数数组的一部分,创建字符序列, 从byte数组的offset开始的length个字节值
  public String(byte[] bytes,int offset,int length)
   
      
  /*
  	跟字符数组相关的
  */

  //利用一个字符数组创建字符数组,代表的字符序列
  public String(char[] value)

  // 创建value字符数组中,从第offset位置开始的count个字符,所代表的字符串对象
  public String(char[] value,int offset,int count)
    
  //知道即可
  public String(String original)  

String特点

String对象不可变

- 对象一旦被创建后,对象所有的状态及属性在其生命周期内不会发生任何变化。

在这里插入图片描述

原因与本质
- String是一个final类,不能被继承,代表不可变的字符序列
- 字符串是常量,用双引号引起来,他们的值在创建之后不可更改
- String对象的内容是存储在字符数组value[ ]中的
在这里插入图片描述

字符串常量池

每当创建字符串常量对象时,JVM会首先检查字符串常量池。
如果该字符串对象引用已经存在常量池中,那么就直接返回常量池中的实例引用
如果字符串对象引用不存在于常量池中,就会实例化该字符串并且将其引用放到常量池中

String两种实例化方式

  • 直接赋值 String s = "abc"
  • 构造方法 String s = new String("abc")

总结:

  • String s = new String("abc"), 再String s1 = "abc"new String 的时候会创建2个对象, 直接赋值的时候, 直接用的是常量池的引用
  • String s1 = "abc", 再String s = new String("abc"), 直接赋值的方式会创建一个对象, new String的时候会创建1个对象

字符串的比较

==与equals方法有什么区别?

  • == ,对于基本数据类型而言,比较的是内容,对于引用数据类型而言,比较的是引用变量,即所指向的地址
  • equals方法是Object的方法,默认是比较2个对象的地址,若要比较内容,应当重写父类方法

String源码中重写的equals方法:

在这里插入图片描述

字符串的拼接

  1. 都是常量的拼接
    等价与拼接后的结果,放不放常量池中,要看常量池中有没有该字符串对象的引用
  2. 有变量的拼接
    原理:通过StringBuilder.append().append().toString在堆上创建出来一个新的字符串对象
    在这里插入图片描述
    xjad:反编译工具

String API

判断功能

用来比较字符串的内容,注意区分大小写
boolean equals(Object obj)
    
忽略字符串大小写比较字符串内容,常见用于比较网址URL
boolean equalsIgnoreCase(String str)
    
判断当前字符串对象是否包含,目标字符串的字符序列
boolean contains(String str)
    
判断当前字符串对象,是否已目标字符串的字符序列开头
boolean startsWith(String str)
    
判断当前字符串,是否以目标字符串对象的字符序列结尾,常用于确定文件后缀名格式
boolean endsWith(String str)
    
判断一个字符串,是不是空字符串 "" 
boolean isEmpty()

获取功能

获取当前字符串对象中,包含的字符个数 "abcd"
int length()  
    
获取字符串对象代表字符序列中,指定位置的字符"abcd"0开始
char charAt(int index) 
    
在当前字符串对象中查找指定的字符,如果找到就返回字符,首次出现的位置,如果没找到返回-1
也可以填字符   "abcd"
int indexOf(int ch) 
    
指定从当前字符串对象的指定位置开始,查找首次出现的指定字符的位置,(如果没找到返回-1)
可以填入字符
int indexOf(int ch,int fromIndex) 
    
查找当前字符串中,目标字符串首次出现的位置(如果包含),找不到,返回-1
这里的位置是指目标字符串的第一个字符,在当前字符串对象中的位置  "abcd"
int indexOf(String str) 

指定,从当前字符串对象的指定位置开始,查找首次出现的指定字符串的位置(如果没找到返回-1)
这里的位置是指目标字符串的第一个字符,在当前字符串对象中的位置
int indexOf(String str,int fromIndex) ,

返回字符串,该字符串只包含当前字符串中,从指定位置开始(包含指定位置字符)到结束的那部分字符串  "abcdef"
String substring(int start)   
    
返回字符串,只包含当前字符串中,从start位置开始(包含),到end(不包含)指定的位置的字符串  
[ , ) --> 左闭右开
String substring(int start,int end) 

转换功能

(重要)获取一个用来表示字符串对象字符序列的,字节数组
byte[] getBytes()
    
(重要)获取的是用来表示字符串对象字符序列的,字符数组
char[] toCharArray() 

    
把字符数组转换成字符串
static String valueOf(char[] chs)

!!! 重要
把各种基本数据类型和对象转换成字符串  100---> "100"
static String valueOf(int i/double...)


把字符串全部转化为小写
String toLowerCase() 
    
把字符串全部转换为大写
String toUpperCase()

字符串拼接,作用等价于 + 实现的字符串拼接
String concat(String str) 

其他功能

String类的替换功能
在新的字符串中,用新(new)字符,替换旧(old)字符  "abcd" 
String replace(char old,char new)  

在新的字符串中,用新的字符串(new), 替换旧(old)字符串
String replace(String old, String new) 


在新的字符串中,去掉开头和结尾的空格字符 "abc"  "abc "
String trim()

分隔功能
将字符串按照符号分隔成字符串数组  "a,b,c,d"
String[] split(String re) 

String类的比较功能
int compareTo(String str)
int compareToIgnoreCase(String str)

关于compareTo方法

  1. 字符串长度一样,逐一比较返回第一个不一样字符的编码值的差值(调用者-参数)
  2. 字符串长度不一样,并且前面的字符都相同,返回数组长度的差值(调用者-参数)
  3. 长度一样,逐位字符也一样,返回0,表示相等

自然排序

Comparable接口

定义

实现此接口的类,其对象数组(array)或对象容器(collection),就可以通过Arrays.sort()或Collections.sort()进行自动排序
对于实现该接口的A类来说,其对象a1.compareTo(a2)方法返回值

- 小于0,表示a1对象小于a2,在自然排序中处于前面的位置
- 大于0,表示a1对象大于a2,在自然排序中处于后面的位置
- 等于0,表示a1对象等于a2

自定义类实现自然排序:

  1. 实现Comparable接口
  2. 重写compareTo方法

举例

class Student implements Comparable<Student>{
    String name;
    int age;
    int score;

    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public int getScore() {
        return score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        // 排序规则
        // 按照年龄从小到大进行排序
        // 按照年龄从大到小进行排序
        //return this.getAge()-o.getAge();
        // 年龄相同的情况下,按照分数从高到低排序
        if (this.getAge() == o.getAge()) {
            return o.getScore() - this.getScore();
        }

        return this.getAge()-o.getAge();
    }

    //@Override
    //public int compareTo(Object o) {
    //    return 0;
    //}
}

Comparator接口

定义

在排序时需要注意一个比较特殊的方法,带比较器的Arrays.sort方法,
sort(T[] a, Comparator<? super T> c)

根据指定比较器产生的顺序对指定对象数组进行排序。
其中Comparator接口的实现类对象就是比较器,该对象通过compare方法传入比较的规则:
表示传入比较规则的int compare(T o1, T o2)方法:
该方法可以看成是o1-o2,如果方法返回负数,o1< o2,相反则大于,只有当方法返回0时,才表示对象相等

在这里插入图片描述

三种方式去实现自然排序:

  1. 手写接口类实现

Student[] students = {s1, s2, s3, s4};

// 手动接口类实现
Arrays.sort(students,new MyComparator());
System.out.println("students = " + Arrays.toString(students));


class MyComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o1.getAge() - o2.getAge();
    }
}
  1. 匿名内部类
        // 2.匿名内部类
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        });
    }
  1. 使用lambda表达式
// 使用lambda表达式
Arrays.sort(students, (stu1, stu2) -> stu2.getAge() - stu1.getAge());

可变长字符串

如果一个空字符串””,让其拼接10000次,效率怎么样? —> 引出了可变长字符串,比传统的 " + " 提高了效率

StringBuffer的构造方法

public StringBuffer() // 默认容量是16

public StringBuffer(int capacity)// 容量是capacity

public StringBuffer(String str)// str的长度+16

StringBuffer的成员方法

注意返回的是StringBuffer对象,不是String对象

获取功能
public int capacity() // 返回当前容量,数组的长度,理论值
public int length() // 返回长度(字符的个数),实际值 
   
添加功能
public StringBuffer append(String s) //将指定的字符串(其他类型有重载方法)追加到此字符序列的尾部
public StringBuffer insert(int offset,String str) //在指定位置把任意类型的数据插入到字符串缓冲区里

删除功能
public StringBuffer deleteCharAt(int index)// 删除指定位置的字符
public StringBuffer delete(int start,int end)// 删除从指定位置开始指定位置结束的内容

替换功能
// 使用给定String中的字符替换词序列的子字符串中的字符
public StringBuffer replace(int start,int end,String str)

反转功能
public StringBuffer reverse()// 将此字符序列用其反转形式取代,返回对象本身

String与StringBuffer之间的相关转换

 // String---->StringBuffer
        String s = "abc";
        StringBuffer sb = new StringBuffer(s);
        System.out.println(sb.reverse());


// StringBuffer---->String
        String s1 = sb.toString();
        System.out.println(s1);

String、StringBuffer和StringBuilder有什么区别?

  • String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改
    • 并且不产生新的未使用对象,不会产生效率问题和空间浪费问题
  • StringBuffer是线程安全的(有synchronized:对共享资源加锁互斥的访问共享数据),StringBuilder是线程不安全的
    • StringBuilder的效率会比StringBuffer效率更高单线程的程序推荐使用StringBuilder
    • 多线程的程序中,应该优先考虑使用StringBuffer,安全性要更重要
    • 它们的效率都比String高很多

intern方法

intern方法是一个native方法,该方法首先会从字符串常量池中检测该对象的引用是否已存在(以Java8版本为标准):
如果存在就返回字符串常量池中,该对象的引用
如果不存在就将存在于堆上的字符串对象的引用存入常量池(注意不会在常量池中创建新对象)

举例


String s1 = "Hello";
String s2 = new String("Hello");
String s3 = new String("World");
String s4 = s2 + s3;
System.out.println(s1 == s2.intern()); // true
System.out.println(s2 == s2.intern()); // false
System.out.println(s3 == s3.intern()); // false
System.out.println(s4 == s4.intern()); // true

-------------------------------------------------

String str = new String("h1") + new String("h2");
String str2 = str.intern();
String str3 = "h1h2";
System.out.println(str == str2); // true
System.out.println(str == str3); // true
System.out.println(str2 == str3); // true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coo1heisenberg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值