JavaSE--String

String概述(掌握)

基本介绍

基本介绍

  • 一个字符串是由多个字符组成的一串数据(字符序列,字符数组)

  • String类代表字符串,Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现

  • 在java.lang包下,是java核心类,最常用类,但是不属于基本数据类型

  • 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)  

Demo

    @Test
    public void myTest(){
        //   //空字符串 ""
        //  public String()
        String s1 = new String();
        System.out.println(s1);
        System.out.println("123");


        //  //利用字节数组,创建字节数组所表示的字符串
        //  // 1. 字符 -> 数值形式  'a' -> 97
        //  // 2. 所以可以用多个字节值,表示多个字符——>即字符序列 public
        //  String(byte[] bytes)
        byte[] bytes = {97, 98, 99};
        String s2 = new String(bytes);
        System.out.println(s2);


        //  //利用字节数数组的一部分,创建字符序列, 从byte数组的offset开始的length个字节值
        //  public String(byte[] bytes,int offset,int length)
        String s3 = new String(bytes, 0, 2);
        System.out.println("s3 = " + s3);

        //  //利用一个字符数组创建字符数组,代表的字符序列
        //  public String(char[] value)
        char[] chars = {'h', 'e', 'l', 'l', 'o'};
        String s4 = new String(chars);
        System.out.println("s4 = " + s4);


        //  // 创建value字符数组中,从第offset位置开始的count个字符,所代表的字符串对象
        //  public String(char[] value,int offset,int count)
        String s5 = new String(chars, 0, 3);
        System.out.println("s5 = " + s5);


        //  //知道即可
        //  public String(String original)
        String s6 = new String("aaa");
        System.out.println("s6 = " + s6);
    }

String特点(重点)

String对象不可变

什么是对象不可变

什么是String对象不可变?
对象一旦被创建后,对象所有的状态及属性在其生命周期内不会发生任何变化。
从对象的角度来看,某个String对象创建完成后,就不能再改变该对象的状态,这就是所谓的对象不可变

  • 对象的状态不改变指的是对象中成员变量不能改变,这包括
    • 基本数据类型成员变量的取值不能改变
    • 引用数据类型成员变量的引用不能指向新的对象
    • 引用数据类型成员变量的引用,所指向的对象的状态也不可改变

例子

1.请键盘录入一个任意字符串s,并用一个temp字符串引用也指向它
这个时候修改temp字符串的内容,请问s字符串的内容会随之改变吗?

    /*
     * 1.请键盘录入一个任意字符串s,并用一个temp字符串引用也指向它
        这个时候修改temp字符串的内容,请问s字符串的内容会随之改变吗?
     * 创建日期:2022/1/13 10:08
     * @return void
     * @author 景天
     */
    @Test
    public void myTest1(){
        // 创建Scanner对象
        Scanner scanner = new Scanner(System.in);

        // nextLine方法 接收键盘数据 s
        String s = scanner.nextLine();
        System.out.println(s);

        // temp 指向
        String temp = s;
        System.out.println("temp = " + temp);

        // 修改temp字符串内容
        temp = "aaa";

        // 输出
        System.out.println("temp = " + temp);
        System.out.println("s = " + s);
    }

image-20220113101711212

注意

  • 并不是把原来的"abc"更改成"aaa",而是新创建了1个对象
  • 修改的知识temp指向

例子

String s = "张三";
 System.out.println("s = " + s);
 s = "hello 张三";
 System.out.println("s = " + s);

输出结果是多少?原因是什么?

输出

张三

hello 张三

image-20220113102122321

原因与本质

  • String是一个final类,代表不可变的字符序列
  • 字符串是常量,用双引号引起来,他们的值在创建之后不可更改
  • String对象的内容是存储在字符数组value[ ]中的

image-20220113104537635

image-20220113104712004

image-20220113105714021

字符串常量池

引例:

    String s1 = "abc";
    String s2 = "abc";
    String s3 = new String("abc");
    System.out.println(s1 == s2);
    System.out.println(s1 == s3);

输出结果,原因是什么?

true

false

什么是字符串常量池

字符串的分配和其他对象分配一样,是需要消耗高昂的时间和空间的,而且字符串使用的非常多

JVM为了提高性能和减少内存的开销,在实例化字符串对象的时候进行了一些优化:

使用字符串常量池。

首先要明确,Java的双引号引起来的字面值常量字符串,它们都是对象。这些对象比较特殊,程序在编译时期就能确定它们的值,编译时期就能作为对象加入“静态常量池”,在类加载时期就能够读取进字符串常量池

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

String两种实例化方式的区别

两种方式

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

区别

  • 方式一只创建了1个对象,在常量池中
  • 方式二创建了2个对象,1个通过new在堆上,另一个在常量池中

image-20220113110211688

常见练习与问题

字符串内容比较
booleanequals(Object anObject) 将此字符串与指定的对象比较。
将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2));// true

String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3 == s4); //false
System.out.println(s3.equals(s4)); // true

String s5 = "hello";
String s6 = "hello";
System.out.println(s5 == s6); // true
System.out.println(s5.equals(s6)); // true



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

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

String中重写的equals方法

image-20220113111700527

字符串拼接
String s = "hello";
S+="world";
sout(s)
String s1 = "Hello";
String s2 = "Hello";
String s3 = "Hel" + "lo"; // 等价于 String s3 = "Hello";
String s4 = "Hel" + new String("lo");
String s5 = new String("Hello");
String s7 = "H";
String s8 = "ello";
String s9 = s7 + s8;
          
System.out.println(s1 == s2);// true
System.out.println(s1 == s3);// 
System.out.println(s1 == s4);
System.out.println(s1 == s9);
System.out.println(s4 == s5);

  • 进行字符串拼接的时候有2种情况
    • 直接在常量池中创建新的拼接对象
    • 在堆上创建新的拼接对象
  • 当参与字符串拼接对的2个字符串,只要有1个引用变量的形式出现时,则会在堆上创建新的字符串对象.
    • 原因是因为参与了运算,无法在编译期确定其值,就不能在编译时期加入常量池
  • 只有参与字符串拼接的2个字符串都是字面值常量的时候,则会在常量池创建拼接对象
    • 如果常量池中已有,则不会创建

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()

Demo

    /*
     * 判断功能
     * 创建日期:2022/1/13 11:29
     * @return void
     * @author 景天
     */
    @Test
    public void myTest1(){
        // 用来比较字符串的内容,注意区分大小写
        //boolean equals(Object obj)

        //忽略字符串大小写比较字符串内容,常见用于比较网址URL
        //boolean equalsIgnoreCase(String str)
        String s1 = "abc";
        String s2 = "ABc";
        System.out.println("s1.equalsIgnoreCase(s2) = " + s1.equalsIgnoreCase(s2));

        //判断当前字符串对象是否包含,目标字符串的字符序列
        //boolean contains(String str)
        System.out.println("s1.contains(\"ab\") = " + s1.contains("ab"));


        //判断当前字符串对象,是否已目标字符串的字符序列开头
        //boolean startsWith(String str)
        System.out.println("s1.startsWith(\"ab\") = " + s1.startsWith("ab"));
        System.out.println("s1.startsWith(\"de\") = " + s1.startsWith("de"));

        //判断当前字符串,是否以目标字符串对象的字符序列结尾,常用于确定文件后缀名格式
        //boolean endsWith(String str)
        System.out.println(s1.endsWith("bc"));

        //判断一个字符串,是不是空字符串 指的不是null 指的是""
        //boolean isEmpty()
        System.out.println("s1.isEmpty() = " + s1.isEmpty());
        System.out.println("\"\".isEmpty() = " + "".isEmpty());
    }

获取功能

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

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

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



Demo

    /*
     * 获取功能
     * 创建日期:2022/1/13 11:37
     * @return void
     * @author 景天
     */
    @Test
    public void myTest2() {
        String s = "abcde";

        // 获取当前字符串对象中,包含的字符个数
        //int length()
        System.out.println("s.length() = " + s.length());

        //获取字符串对象代表字符序列中,指定位置的字符
        //char charAt(int index)
        char c = s.charAt(0);
        System.out.println(c);


        //在当前字符串对象中查找指定的字符,如果找到就返回字符,首次出现的位置,如果没找到返回-1
        //也可以填字符
        //int indexOf(int ch)  从0开始算
        int index = s.indexOf(100);
        System.out.println(index);


        //指定从当前字符串对象的指定位置开始,查找首次出现的指定字符的位置,(如果没找到返回-1)
        //可以填入字符
        //int indexOf(int ch,int fromIndex)
        int index1 = s.indexOf(99, 1);
        System.out.println("index1 = " + index1);


        //查找当前字符串中,目标字符串首次出现的位置(如果包含),找不到,返回-1
        //这里的位置是指目标字符串的第一个字符,在当前字符串对象中的位置
        //int indexOf(String str)
        int index2 = s.indexOf("de");
        System.out.println(index2);


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


        //返回字符串,该字符串只包含当前字符串中,从指定位置开始(包含指定位置字符)到结束的那部分字符串
        //String substring(int start)
        String substring = s.substring(3);
        System.out.println("substring = " + substring);


        //返回字符串,只包含当前字符串中,从start位置开始(包含),到end(不包含)指定的位置的字符串
        // [ )
        //String substring(int start,int end)
        String substring1 = s.substring(2, 3);
        System.out.println("substring1 = " + substring1);

    }

课堂练习:
1:遍历获取字符串中的每一个字符
2:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)

   /*
     *课堂练习:
        1:遍历获取字符串中的每一个字符
        2:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
     * 创建日期:2022/1/13 11:46
     * @return void
     * @author 景天
     */
    @Test
    public void myTest3(){
        String s = "abc00123AFg";

        // 定义3个计数器

        // 统计大写的
        int countUpper = 0;

        // 统计小写的
        int countLower = 0;

        // 统计数字的
        int countDigital = 0;

        // 遍历该字符串
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 做判断 计数器的值相应的+1
            if (c >= 'A' && c <= 'Z') {
                countUpper += 1;
            } else if (c >= 'a' && c <= 'z') {
                countLower += 1;
            }else {
                countDigital += 1;
            }
            // 输出
        }
        System.out.println("countUpper = " + countUpper);
        System.out.println("countLower = " + countLower);
        System.out.println("countDigital = " + countDigital);


    }

自然排序(掌握)

Comparable接口

Comparator接口

可变长字符串(掌握)

StringBuffer

构造方法

成员方法

intern方法(了解)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值