Java:20-String类的概述和使用

String类的概述和使用

String类的概念------------------------------
public final class String
extends Object
implements Serializable, Comparable<String>, CharSequence
//Serializable,序列化接口
//Comparable<String>,比较器接口
//CharSequence,字符序列接口
java.lang.String类用于描述字符串
IDEA里面按下ctrl+shift+a到帮助里的Find Action…里面,可以搜索很多东西,如里面的Classes里可以搜索源码,如String类的源码
由于java.lang.String够浪,所以不用导包,java.lang.* 是默认导入的,如果你导入了对应的包,那么他不操作,否则默认导入
多个字符"串"起来,就叫字符串,由"abc"双引号引起来的固定数值就是字面值
与直接量类似,也可叫直接量,因为是直接写出来的
直接量是直接写出来的,如直接写出来的整数数据,小数数据等
Java程序中所有的字符串字面值都可以使用该类的对象加以描述,如:“abc”
该类由final关键字修饰,表示该类不能被继承
从jdk1.9开始该类的底层不使用char[]来存储数据,而是改成 byte[]加上编码标记,从而节约了一些空间
因为char两字节,byte一个字节,所以节约空间
该类描述的字符串内容是个常量不可更改,因此可以被共享使用
//如下
String str1 = "abc"; //默认处理String的构造方法的(String是基础类型,跟int a = 1中的1赋值一样,只不过String是一个类,这里jvm会处理的,反正二级制会完成的,不用特别在意)
//其中"abc"这个字符串是个常量不可改变
str1 = "123";
//将"123"字符串的地址赋值给变量str1
//改变str1的指向并没有改变指向的内容  
//上述是从常量池里创建后给Str1

//一般来说常量池对比堆来说只是唯一而已,具体操作基本可以沿用(如某些方法,如equals),可以认为常量池是特殊的堆

在这里插入图片描述

在这里插入图片描述

package com.lagou.task12;

/**
 *
 */
public class StringPoolTest {
    public static void main(String[] args) {
        //验证一下常量池的存在
        //到目前为止,基本只有String这个特殊类除了new的方式外,还可以直接字符串赋值
        //(包装类除外)
        String str1 = "abc";
        String str2 = "abc";
        System.out.println(str1 == str2); //比较地址 true
        //从常量值里找,在第一个abc创建时,若继续赋值abc,就会赋值创建的abc,这个直接创建的地方是常量池
        String str3 = new String("abc");
        System.out.println(str2 == str3); //false
        //这里创建了两个对象,一个"abc",也算一个,但"abc"是从常量池里找
        //一个在常量池,一个在堆区,但str3指定堆区内存空间,即地址不同
    }
}

常量池的概念------------------------------
由于String类型描述的字符串内容是常量不可改变,因此Java虚拟机将首次出现的字符串放入常量池中
若后续代码中出现了相同字符串内容则直接使用池中已有的字符串对象而无需申请内存及创建对象,从而提高了性能
常量也是固定不变的数,如直接写的1,1.1等等,都可以叫做常量,即用final修饰的也可叫常量
只要是常量都有常量优化机制,如byte a = 1+2,由优化机制将1+2化成3(编译期操作的哦),赋值给a,当然变量不可以哦
package com.lagou.task12;

public class StringExamTest {

    public static void main(String[] args) {

        // 1.请问下面的代码会创建几个对象?分别存放在什么地方?
        //String str1 = "hello";  // 1个对象  存放在常量池中
        //String str1 = new String("helo"); // 2个对象  1个在常量池中,1个在堆区

        // 2.常量池和堆区对象的比较
        String str1 = "hello";  // 常量池
        String str2 = "hello";  // 常量池
        String str3 = new String("hello"); // 堆区
        String str4 = new String("hello"); // 堆区

        System.out.println(str1 == str2);       // 比较地址  true
        System.out.println(str1.equals(str2));  // 比较内容  true
        System.out.println(str3 == str4);       // 比较地址  false
        System.out.println(str3.equals(str4));  // 比较内容  true
        System.out.println(str2 == str4);       // 比较地址  false
        System.out.println(str2.equals(str4));  // 比较内容 true

        System.out.println("------------------------------------------------------------");
        // 3.常量有优化机制,变量没有
        String str5 = "abcd";
        String str6 = "ab" + "cd";  // 常量优化机制  "abcd",除了1+2这样的操作,字符串也是可以的,简单来说,只要不是变量基本都会操作,既然是编译期的,那么运行时,就相当于拿取"abcd",自然是true
        System.out.println(str5 == str6); // 比较地址  true

        String str7 = "ab";
        String str8 = str7 + "cd"; // 没有常量优化
        //通过加号,即有新的对象产生(相当于new),然后将该对象给str8,这就是为什么是false的原因,没有操作常量池哦
        System.out.println(str5 == str8); // 比较地址 false

 //表达式str7 + "cd"会在运行时被转换为"ab" + "cd",然后生成一个新的字符串"abcd",这个新的字符串在堆内存中创建,并且不会放入字符串常量池中。因为字符串常量池主要用来存储编译期确定的常量,而不是在运行时动态生成的字符串


    }
}

常用的构造方法------------------------------
String(),使用无参方式构造对象得到空字符序列
String(byte[] bytes, int offset, intlength),使用bytes数组中下标从offset位置开始的length个字节来构造对象
String(byte[] bytes),使用bytes数组中的所有内容构造对象
String(char[] value, int offset, intcount),使用value数组中下标从offset位置开始的count个字符来构造对象
String(char[] value),使用value数组中的所有内容构造对象
String(String original),根据参数指定的字符串内容来构造对象,新创建对象为参数对象的副本
package com.lagou.task12;

public class StringConstructorTest {

    public static void main(String[] args) {
        // 1.使用无参方式构造对象并打印
        //String(),使用无参方式构造对象得到空字符序列
        String str1 = new String();
        // "" 表示空字符串对象,有对象只是里面没有内容,因为底层就是这样的
        // null 表示空,连对象都没有
        System.out.println("str1 = " + str1); // ""  自动调用toString方法

        System.out.println("----------------------------------------------------");
        // 2.使用参数指定的byte数组来构造对象并打印
        // 'a' - 97
        byte[] bArr = {97, 98, 99, 100, 101};
        // 使用字节数组中的一部分内容来构造对象,表示使用数组bArr中下标从1开始的3个字节构造字符串对象
        // 构造字符串的思路:就是先将每个整数翻译成对应的字符,再将所有的字符串起来。
        // 98 - 'b'   99 - 'c'  100 - 'd'   => bcd
        //String(byte[] bytes, int offset, intlength)
        //使用bytes数组中下标从offset位置开始的length个字节来构造对象
        String str2 = new String(bArr, 1, 3);
        System.out.println("str2 = " + str2); // bcd

        // 使用整个字节数组来构造字符串对象
        //String(byte[] bytes),使用bytes数组中的所有内容构造对象
        String str3 = new String(bArr);
        System.out.println("str3 = " + str3); // abcde

        System.out.println("----------------------------------------------------");
        // 3.使用字符数组来构造字符串对象
        char[] cArr = {'h', 'e', 'l', 'l', 'o'};
        // 使用字符数组中的一部分内容来构造对象
        // 思路:直接将字符串起来
        //String(char[] value, int offset, intcount)
        //使用value数组中下标从offset位置开始的count个字符来构造对象
        String str4 = new String(cArr, 2, 2);
        System.out.println("str4 = " + str4); // ll
        // 使用整个字符数组来构造对象
        //String(char[] value),使用value数组中的所有内容构造对象
        String str5 = new String(cArr);
        System.out.println("str5 = " + str5); // hello

        System.out.println("----------------------------------------------------");
        // 4.使用字符串来构造字符串对象
        //String(String original),根据参数指定的字符串内容来构造对象,新创建对象为参数对象的副本
        String str6 = new String("world");
        System.out.println("str6 = " + str6); // world
    }
}

常用的成员方法------------------------------
String toString(),返回字符串本身
byte[] getBytes(),将当前字符串内容转换为byte数组并返回
char[] toCharArray(),用于将当前字符串内容转换为char数组并返回
char charAt(int index),方法charAt用于返回字符串指定位置的字符
int length(),返回字符串字符序列的长度
boolean isEmpty(),判断字符串是否为空
package com.lagou.task12;

public class StringByteCharTest {

    public static void main(String[] args) {

        // 1.创建String类型的对象并打印
        String str1 = new String("world");
        System.out.println("str1 = " + str1); // world

        System.out.println("-----------------------------------------------");
        // 2.实现将String类型转换为byte数组类型并打印
        // 思路:先将字符串拆分为字符,将再每个字符转换为byte类型,也就是获取所有字符的ASCII
        //byte[] getBytes(),将当前字符串内容转换为byte数组并返回
        byte[] bArr = str1.getBytes();
        for (int i = 0; i < bArr.length; i++) {
            System.out.println("下标为i的元素是:" + bArr[i]);
        }
        // 将byte数组转回String类型并打印
        String str2 = new String(bArr);
        System.out.println("转回字符串为:" + str2); // world

        System.out.println("-----------------------------------------------");
        // 3.实现将String类型转换为char数组类型并打印
        // 思路:将字符串拆分为字符并保存到数组中
        //char[] toCharArray(),用于将当前字符串内容转换为char数组并返回
        char[] cArr = str1.toCharArray();
        for (int i = 0; i < cArr.length; i++) {
            System.out.println("下标为" + i + "的字符是:" + cArr[i]);
        }
        // 将char数组转回String类型并打印
        String str3 = new String(cArr);
        System.out.println("转回字符串为:" + str3); // world
    }
}

package com.lagou.task12;

public class StringCharTest {

    public static void main(String[] args) {

        // 1.构造String类型的对象并打印
        String str1 = new String("hello");
        System.out.println("str1 = " + str1); // hello
        // 2.获取字符串的长度和每个字符并打印
        //int length(),返回字符串字符序列的长度
        System.out.println("字符串的长度是:" + str1.length()); // 5
        //char charAt(int index),方法charAt用于返回字符串指定位置的字符
        System.out.println("下标为0的字符是:" + str1.charAt(0)); // h
        System.out.println("下标为1的字符是:" + str1.charAt(1)); // e
        System.out.println("下标为2的字符是:" + str1.charAt(2)); // l
        System.out.println("下标为3的字符是:" + str1.charAt(3)); // l
        System.out.println("下标为4的字符是:" + str1.charAt(4)); // o
        //System.out.println("下标为5的字符是:" + str1.charAt(5));
        //StringIndexOutOfBoundsException 字符串下标越界异常

        System.out.println("----------------------------------------------");
        // 3.使用for循环获取所有字符
        for (int i = 0; i < str1.length(); i++) {
            System.out.println("下标为" + i + "的字符是:" + str1.charAt(i)); // h e l l o
        }

        System.out.println("----------------------------------------------");
        // 4.判断字符串是否为空
        System.out.println(0 == str1.length()? "字符串为空": "字符串不为空"); // 不为空
        //boolean isEmpty(),判断字符串是否为空
        System.out.println(str1.isEmpty()? "字符串为空": "字符串不为空");     // 不为空

        System.out.println("----------------------------------------------");
        // 5.笔试考点
        // 使用两种方式实现字符串"12345"转换为整数12345并打印
        String str2 = new String("12345");
        // 方式一:调用Integer类中的parseInt()方法即可
        int ia = Integer.parseInt(str2);
        System.out.println("转换出来的整数是:" + ia); // 12345
        // 方式二:利用ASCII来实现类型转换并打印
        // '1' - '0' => 1  '2' - '0' => 2  ...
        int ib = 0;
        for (int i = 0; i < str2.length(); i++) {
            ib = ib*10 + (str2.charAt(i) - '0'); // 1 12 ...
        }
        System.out.println("转换出来的结果是:" + ib); // 12345

        System.out.println("----------------------------------------------");
        // 如何实现整数到字符串的转换
        //String str3 = String.valueOf(ib);
        String str3 = "" + ib; // 推荐使用
        System.out.println("str3 = " + str3); // 12345
    }
}

案例题目------------------------------
判断字符串"上海自来水来自海上"是否为回文并打印"
所谓回文是指一个字符序列无论从左向右读还是从右向左读都是相同的句子
package com.lagou.task12;

public class StringJudgeTest {
   /* public String huiwen(String st){
        //二分法
        for(int i = 0; i<st.length()/2; i++){
            //判断第一个和最后一个的字符是否相等
            if(st.charAt(i) != st.charAt(st.length()-1-i) ){
                return "不是回文";
            }
        }
        return "是回文";
    }*/
    public static void main(String[] args) {

        // 1.创建字符串对象并打印
        String str1 = new String("上海自来水来自海上");
        System.out.println("str1 = " + str1); // 上海自来水来自海上   9
        // 2.判断该字符串内容是否为回文并打印
        for (int i = 0; i < str1.length()/2; i++) {
            if (str1.charAt(i) != str1.charAt(str1.length()-i-1)) {  // 0和8   1和7  2和6  3和5
                System.out.println(str1 + ":不是回文!");
                return;  // 仅仅是用于实现方法的结束
            }
        }
        System.out.println(str1 + ":是回文!");
    }
}

int compareTo(String anotherString),用于比较调用对象和参数对象的大小关系
int compareToIgnoreCase(String str),不考虑大小写,也就是'a''A'是相等的关系
案例题目------------------------------
编程实现字符串之间大小的比较并打印
package com.lagou.task12;

public class StringCompareTest {

    public static void main(String[] args) {

        // 1.构造String类型的对象并打印
        String str1 = new String("hello");
        System.out.println("str1 = " + str1); // hello

        // 2.使用构造好的对象与其它字符串对象之间比较大小并打印
        //int compareTo(String anotherString),用于比较调用对象和参数对象的大小关系
        //比较位置,看字符的(Unicode或UNICODE,用Ascii或ASCII也差不多)比较
        //调用对象减去参数对象,返回一个正负数,相同返回0
        System.out.println(str1.compareTo("world"));  // 'h' - 'w' => 104 - 119 => -15
        //相同的就比较后面的,直到都相同
        System.out.println(str1.compareTo("haha"));   // 'e' - 'a' => 101 - 97  => 4
        System.out.println(str1.compareTo("hehe"));   // 'l' - 'h' => 108 - 104 => 4
        System.out.println(str1.compareTo("heihei")); // 'l' - 'i' => 108 - 105 => 3
        //最前面有完全相同的,则比较长度值
        System.out.println(str1.compareTo("helloworld")); // 长度: 5 - 10 => -5
        System.out.println(str1.compareTo("HELLO"));  // 'h' - 'H' => 104 - 72 => 32
        //int compareToIgnoreCase(String str),不考虑大小写,也就是'a'和'A'是相等的关系
        System.out.println(str1.compareToIgnoreCase("HELLO")); // 0
    }
}
String concat(String str),用于实现字符串的拼接
boolean contains(CharSequence s),用于判断当前字符串是否包含参数指定的内容 //CharSequence,字符序列接口
String toLowerCase(),返回字符串的小写形式
String toUpperCase(),返回字符串的大写形式
String trim(),返回去掉前导和后继空白的字符串
boolean startsWith(String prefix),判断字符串是否以参数字符串开头
boolean startsWith(String prefix, int toffset),从指定位置开始是否以参数字符串开头
boolean endsWith(String suffix),判断字符串是否以参数字符串结尾
案例题目------------------------------
编程实现上述方法的使用
package com.lagou.task12;

public class StringManyMethodTest {

    public static void main(String[] args) {
        String a = "1";
        //String concat(String str),用于实现字符串的拼接
        System.out.println(a.concat("2")); //12
        // 1.构造String类型的对象并打印
        String str1 = new String("     Let Me Give You Some Color To See See!");
        System.out.println("str1 = " + str1); //      Let Me Give You Some Color To See See!

        // 2.实现各种成员方法的调用和测试
        //boolean contains(CharSequence s),用于判断当前字符串是否包含参数指定的内容
        boolean b1 = str1.contains("some");
        System.out.println("b1 = " + b1); // false  区分大小写
        b1 = str1.contains("Some");
        System.out.println("b1 = " + b1); // true

        System.out.println("----------------------------------------------");
        // 将所有字符串转换为大写  小写  以及去除两边的空白字符
        //String toUpperCase(),返回字符串的大写形式
        String str2 = str1.toUpperCase();
        System.out.println("str2 = " + str2); //    LET ME GIVE YOU SOME COLOR TO SEE SEE!
        System.out.println("str1 = " + str1); //    Let Me Give You Some Color To See See!   常量
        //常量不可改变
        //String toLowerCase(),返回字符串的小写形式
        String str3 = str1.toLowerCase();
        System.out.println("str3 = " + str3); //    let me give you some color to see see!
        System.out.println("str1 = " + str1); //    Let Me Give You Some Color To See See!
        //String trim(),返回去掉前导和后继空白的字符串
        //实际作用:在注册时,若不小心在最前面和最后面多打一个空格,那么登录时,会一直登录不上
        //则影响体验(明明我输入对了,为什么登录不上呢(〃>目<)),即需要去掉最前面和最后面的空格
        String str4 = str1.trim();
        System.out.println("str4 = " + str4); //Let Me Give You Some Color To See See!     奇点
        System.out.println("----------------------------------------------");
        // 判断字符串是否以...开头  以...结尾
        //boolean startsWith(String prefix),判断字符串是否以参数字符串开头
        b1 = str1.startsWith("Let");
        System.out.println("b1 = " + b1); // false
        b1 = str1.startsWith(" ");
        System.out.println("b1 = " + b1); // true
        // 从下标5开始是否以"Let"开头
        //boolean startsWith(String prefix, int toffset),从指定位置开始是否以参数字符串开头
        b1 = str1.startsWith("Let", 5);
        System.out.println("b1 = " + b1); // true
        //boolean endsWith(String suffix),判断字符串是否以参数字符串结尾
        b1 = str1.endsWith("See");
        System.out.println("b1 = " + b1); // false
        b1 = str1.endsWith("See!");
        System.out.println("b1 = " + b1); // true
    }
}

boolean equals(Object anObject),用于比较字符串内容是否相等并返回
int hashCode(),获取调用对象的哈希码值
boolean equalsIgnoreCase(String anotherString),用于比较字符串内容是否相等并返回,不考虑大小写
如:'A''a'是相等
案例题目------------------------------
提示用户从键盘输入用户名和密码信息,若输入"admin"和"123456"则提示"登录成功,欢迎使用"
否则提示"用户名或密码错误,您还有n次机会",若用户输入三次后依然错误则提示"账户已冻结,请联系客服人员!"
package com.lagou.task12;

import java.util.Scanner;

public class StringEqualsTest {

    public static void main(String[] args) {
        String a = "1";
        //int hashCode(),获取调用对象的哈希码值
        System.out.println(a.hashCode());
        Scanner sc = new Scanner(System.in);
        for (int i = 3; i > 0; i--) {
            // 1.提示用户从键盘输入用户名和密码信息并使用变量记录
            System.out.println("请输入您的用户名和密码信息:");
            String userName = sc.next();
            String password = sc.next();

            // 2.判断用户名和密码是否为"admin"和"123456"并给出提示
            //if ("admin".equals(userName) && "123456".equals(password)) {
            //boolean equals(Object anObject),用于比较字符串内容是否相等并返回
            //boolean equalsIgnoreCase(String anotherString)
            //用于比较字符串内容是否相等并返回,不考虑大小写,如:'A'和'a'是相等
            if ("admin".equalsIgnoreCase(userName) && "123456".equals(password)) { //null instanceof String的结果是false
                //之所以不用userName和password来使用方法,主要怕他为null
                //即让他们当参数,可以防止空指针异常
                System.out.println("登录成功,欢迎使用!");
                break;
            } //else {
            if (1 == i) {
                System.out.println("账户已冻结,请联系客服人员!");
            } else {
                System.out.println("用户名或密码错误,您还有" + (i - 1) + "次机会!");
            }
            //}
        }
        // 关闭扫描器
        sc.close();
    }
}

int indexOf(int ch),用于返回当前字符串中参数ch指定的字符第一次出现的下标
int indexOf(int ch, int fromIndex),用于从fromIndex位置开始查找ch指定的字符
int indexOf(String str),在字符串中检索str返回其第一次出现的位置,若找不到返回-1
int indexOf(String str, int fromIndex),表示从字符串的fromIndex位置开始检索str第一次出现的位置
//上面四个方法是从左向右查找
//下面四个方法是从右向左查找
int lastIndexOf(int ch),用于返回参数ch指定的字符最后一次出现的下标
int lastIndexOf(int ch, int fromIndex),用于从fromIndex位置开始查找ch指定字符出现的下标
int lastIndexOf(String str),返回str指定字符串最后一次出现的下标
int lastIndexOf(String str, int fromIndex),用于从fromIndex位置开始反向搜索的第一次出现的下标
案例题目------------------------------
编写通用的代码可以查询字符串"Good Good Study, Day Day Up!"中所有"Day"出现的索引位置并打印出来
package com.lagou.task12;

public class StringIndexTest {

    public static void main(String[] args) {

        // 1.构造String类型的对象并打印
        String str1 = new String("Good Good Study, Day Day Up!");
        System.out.println("str1 = " + str1); // Good Good Study, Day Day Up!

        // 2.实现字符串中指定字符和字符串的查找功能
        //int indexOf(int ch),用于返回当前字符串中参数ch指定的字符第一次出现的下标
        //之所以放int类型,首先因为int a = 'a',是从小到大,int也可以描述其他的类型
        int pos = str1.indexOf('g');
        System.out.println("pos = " + pos); // -1  代表查找失败
        pos = str1.indexOf('G');
        System.out.println("pos = " + pos); // 0   该字符第一次出现的索引位置
        // 表示从下标0开始查找字符'G'第一次出现的索引位置,包含0
        //int indexOf(int ch, int fromIndex),用于从fromIndex位置开始查找ch指定的字符
        pos = str1.indexOf('G', 0);
        System.out.println("pos = " + pos); // 0
        pos = str1.indexOf('G', 1);
        System.out.println("pos = " + pos); // 5

        System.out.println("------------------------------------------------------");
        // 查找字符串
        //int indexOf(String str),在字符串中检索str返回其第一次出现的位置,若找不到返回-1
        pos = str1.indexOf("day");
        System.out.println("pos = " + pos); // -1
        pos = str1.indexOf("Day");
        System.out.println("pos = " + pos); // 17   字符串中第一个字符的下标
        //int indexOf(String str, intfromIndex),表示从字符串的fromIndex位置开始检索str第一次出现的位置
        pos = str1.indexOf("Day", 17);
        System.out.println("pos = " + pos); // 17   字符串中第一个字符的下标
        pos = str1.indexOf("Day", 18);
        System.out.println("pos = " + pos); // 21   字符串中第一个字符的下标

        System.out.println("------------------------------------------------------");
        // 编写通用代码实现将字符串str1中所有"Day"出现的索引位置找到并打印出来
        pos = str1.indexOf("Day");
        while (-1 != pos) {
            System.out.println("pos = " + pos); // 17
            pos = str1.indexOf("Day", pos+1);
        }
        //但这里可以发现,当找到Day时,ay这两个字符,还是会判断
        //那么我们可以优化以下
        System.out.println("------------------------------------------------------");
        // 优化一下
        pos = 0;
        while ((pos = str1.indexOf("Day", pos)) != -1) {
            System.out.println("pos = " + pos);
            pos += "Day".length();
        }
        //可以发现,当我们找到Day时,直接跳过ay的判断了,即优化了,只是这里而已,因为可能后面的会连着变成Day,所以只是这里优化,并不是一个好的查找哦
        //上面四个方法是从左向右查找
        //下面四个方法是从右向左查找
        //查找都只从某个位置到最左或最右,不会重头查找
        System.out.println("------------------------------------------------------");
        // 3.实现字符和字符串内容的反向查找
        //int lastIndexOf(int ch),用于返回参数ch指定的字符最后一次出现的下标
        pos = str1.lastIndexOf('G');
        System.out.println("pos = " + pos); // 5
        // 从下标5的位置开始反向查找
        //int lastIndexOf(int ch, intfromIndex),用于从fromIndex位置开始查找ch指定字符出现的下标
        pos = str1.lastIndexOf('G', 5);
        System.out.println("pos = " + pos); // 5

        pos = str1.lastIndexOf('G', 6);
        System.out.println("pos = " + pos); // 5

        pos = str1.lastIndexOf('G', 4);
        System.out.println("pos = " + pos); // 0

        System.out.println("------------------------------------------------------");
        //int lastIndexOf(String str),返回str指定字符串最后一次出现的下标
        pos = str1.lastIndexOf("Day");
        System.out.println("pos = " + pos); // 21
        //int lastIndexOf(String str, intfromIndex),用于从fromIndex位置开始反向搜索的第一次出现的下标
        pos = str1.lastIndexOf("Day",  21);
        System.out.println("pos = " + pos); // 21
        pos = str1.lastIndexOf("Day", 20);
        System.out.println("pos = " + pos); // 17
        pos = str1.lastIndexOf("Day", 15);
        System.out.println("pos = " + pos); // -1
    }
}

String substring(int beginIndex, int endIndex)
返回字符串中从下标beginIndex(包括)开始到endIndex(不包括)结束的子字符串
String substring(int beginIndex),返回字符串中从下标beginIndex(包括)开始到字符串结尾的子字符串
案例题目------------------------------
提示用户从键盘输入一个字符串和一个字符,输出该字符(不含)后面的所有子字符串
package com.lagou.task12;

import java.util.Scanner;

public class SubStringTest {

    public static void main(String[] args) {

        // 1.构造String类型的对象并打印
        String str1 = new String("Happy Wife, Happy Life!");
        System.out.println("str1 = " + str1); // Happy Wife, Happy Life!

        // 2.获取字符串中的一部分内容并打印
        // 表示从当前字符串中下标12开始获取子字符串
        //String substring(int beginIndex)
        //返回字符串中从下标beginIndex(包括)开始到字符串结尾的子字符串
        String str2 = str1.substring(12);
        System.out.println("str2 = " + str2); // Happy Life!
        // 可以取到6但是取不到10
        //String substring(int beginIndex, int endIndex)
        //返回字符串中从下标beginIndex(包括)开始到endIndex(不包括)结束的子字符串
        String str3 = str1.substring(6, 10);
        System.out.println("str3 = " + str3); // Wife

        System.out.println("---------------------------------------------------------");
        // 3.获取输入字符串中从输入字符起的子字符串内容
        System.out.println("请输入一个字符串:");
        Scanner sc = new Scanner(System.in);
        String str4 = sc.next();
        System.out.println("请输入一个字符:");
        String str5 = sc.next();
        // 从str4中查找str5第一次出现的索引位置
        int pos = str4.indexOf(str5);
        System.out.println("pos = " + pos);
        // 根据该位置获取子字符串
        String str6 = str4.substring(pos+1);
        System.out.println("获取到的子字符串是:" + str6);
    }
}

在Java中几乎所有方法都是前面包含,后面不包含
//如
//Math.random();[0.0,1.0)
static double random(),返回0.01.0的随机数,[0.0 ~ 1.0),包括0.0,不包括1.0
实际上String是一个包含了Char数组的类,也是为什么String比较特殊,与Char有联系,由于String非常重要,所以有上面的一些独有的性质,如常量池等等
正则表达式的概念------------------------------
正则表达式本质就是一个"规则字符串",可以用于对字符串数据的格式进行验证,以及匹配、查找、替换等操作
该字符串通常使用^运算符作为开头标志,使用$运算符作为结尾标志,当然也可以省略
正则表达式也称规则表达式,其实也可以说是字符串,只是存在一些规则的操作而已,就比如遇到1变成2等等类似的规则,或者说只能大于6等等类似的规则
正则表达式的规则------------------------------
[abc],可以出现a、b、c中任意一个字符
[^abc],可以出现任何字符,除了a、b、c的任意字符
[a-z],可以出现a、b、c、……、z中的任意一个字符
[a-zA-Z0-9],可以出现a~z、A~Z0~9中任意一个字符
.(这是一个点)  =>  任意一个字符(通常不包含换行符),这里需要注意:再split分割.时,一般需要\\来进行转义,大多数情况下,正则里面的\\除了特殊的字母或者符号(如\\d),一般就是他自己,大多数正则都是如此,当然,不同语言都可能也会不同,因为正则的处理可能不同,再怎么说,这只是正则表达式的一个规定而已
\d,任意一个数字字符,相当于[0-9]
\D,任意一个非数字字符
\s,空白字符,相当于[\t\n\xOB\f\r]
\S,非空白字符
\w,任意一个单词字符,相当于[a-zA-Z_0-9],包括下划线
\W,任意一个非单词字符
[\t\n\xOB\f\r]:\t制表符,\n换行符,\xOb垂直制表符,\f换页符(将当前位置移到下一页的开头),\r回车不换行
//很多用户和邮箱的规则就是由数字,字母,下划线组成
 //当然,有些并不会多次使用,具体可以看这个:https://m.runoob.com/java/java-regular-expressions.html
 //注意:上面的\xOb可能操作不了,他们基本是直接使用的,用来比较原来字符串同样数据的,这里要注意哦:
    String a = "a\nb";
        System.out.println(a);
        boolean matches = a.matches("a\nb");

//其中\r会消除a
X?,表示X可以出现一次或一次也没有,也就是0 ~ 1X*,表示X可以出现零次或多次,也就是0 ~ n次
X+,表示X可以出现一次或多次,也就是1 ~ n次
X{n},表示X可以出现恰好 n 次
X{n,},表示X可以出现至少 n 次,也就是>=n次
X{n,m},表示X可以出现至少 n 次,但是不超过 m 次,也就是>=n并且<=m次
正则表达式相关的方法------------------------------
(regular expression)是正则表达式的全称
boolean matches(String regex),判断当前正在调用的字符串是否匹配参数指定的正则表达式规则
其中regex最好是正则表达式的字符串,当然其他字符串也可以,但通常都是正则表达式的字符串
案例题目------------------------------
使用正则表达式描述一下银行卡密码的规则:要求是由6位数字组成
使用正则表达式描述一下QQ号码的规则:要求是由非0开头的5~15位数组成
使用正则表达式描述一下手机号码的规则:要求是由1开头,第二位数是3、4、5、7、8中的一位,总共11位
描述身份证号码的规则:总共18位
6位数字代表地区,4位数字代表年,2位数字代表月,2位数字代表日期, 3位数字代表个人,最后一位可能数字也可能是X
package com.lagou.task12;

import java.util.Scanner;

public class StringRegTest {

    public static void main(String[] args) {
        String a = "[0-9]{3}";
        String b = "122";
        System.out.println(a.matches(b)); //false 表示用a字符串判断b的正则表达式,但很明显会是false
        // 1.定义描述规则的正则表达式字符串并使用变量记录
        // 正则表达式只能对数据格式进行验证,无法对数据内容的正确性进行检查
        // 内容的正确性检查需要后台查询数据库
        // 描述银行卡密码的规则:由6位数字组成
        //[a-z],可以出现a、b、c、……、z中的任意一个字符
        //X{n},表示X可以出现恰好 n 次
        //String reg = "^[0-9]{6}$";
        //使用^运算符作为开头标志,使用$运算符作为结尾标志,当然也可以省略
        //String reg = "[0-9]{6}";
        //\d,任意一个数字字符,相当于[0-9],\d在字符串里需要转义,如\\d,即要加斜杆,
        //有些不需要加斜杠,如\t,简单来说,带有自己作用的不用,因为他本来作用与字符串,而其他需要转义后才会识别,而不是先识别了,注意可能有其他的操作,比如\\+也算一个+,即会使得\+的,这里为了让你明白正则表达式为什么出现两个\\的原因:
        //我们知道在matches后面的参数,他首先需要是一个字符串,也就是说,该字符串你总要确定下来吧,那么一些使得操作该字符串的自然会起作用,使得该字符串发生改变,而对于\d来说他并不能符合字符串本身,那么为了在该字符串中加上即需要\\d,于是最终的字符串就确认了,当确认后,被正则识别,于是\d被识别生效了,也就是说,先满足自己,然后满足正则,你自己都没有确定好,那么正则怎么操作你呢,而由于字符串必然会进入的,那么正则内部实际上会将所有的\\的操作都使得变成一个,如\\+,\\],而并非给他赋值其他的功能(如\\d),至此,正则表达式说明完成
        //String reg = "\\d{6}";
        // 使用正则表达式描述一下QQ号码的规则:要求是由非0开头的5~15位数字组成
        //X{n,m},表示X可以出现至少 n 次,但是不超过 m 次,也就是>=n并且<=m次
        //String reg = "[1-9]\\d{4,14}";
        //正则表达式的一些操作只服务于前一个,如这里{4,14}只服务于\\d
        //使用正则表达式描述一下手机号码的规则:要求是由1开头,第二位数是3、4、5、7、8中的一位,总共11位
        //String reg = "1[34578]\\d{9}";
        //描述身份证号码的规则
        //总共18位,6位数字代表地区,4位数字代表年,2位数字代表月,2位数字代表日期, 3位数字代表个人
        //最后一位可能数字也可能是X。
        String reg = "(\\d{6})(\\d{4})(\\d{2})(\\d{2})(\\d{3})([0-9|X])";
        //[0-9|X]中|是或的含义
        //()代表一组,里面可以写规则,也可以在后面加东西,通常也可以不加,只是方便看
        //如([0-9])+,表示[0-9]可以出现一次或多次,也就是1 ~ n次,当然[0-9]+也可以
        //即[0-9]可以出现一次到多次
        // 2.提示用户从键盘输入指定的内容并使用变量记录
        Scanner sc = new Scanner(System.in);
        while(true) {
            //System.out.println("请输入您的银行卡密码:");
            //System.out.println("请输入您的QQ号码:");
            //System.out.println("请输入您的手机号码:");
            System.out.println("请输入您的身份证号码:");
            String str = sc.next();

            // 3.判断用户输入的字符串内容是否满足指定的规则并打印
            if (str.matches(reg)) {
                //System.out.println("银行卡密码的格式正确!");
                System.out.println("输入字符串的格式正确!");
                break;
            } else {
                //System.out.println("银行卡密码的格式错误!");
                System.out.println("输入字符串的格式错误!");
            }
        }
    }
}

String[] split(String regex),参数regex为正则表达式,以regex所表示的字符串为分隔符,将字符串拆分成字符串数组,但是如果首部是该分隔符,那么认为首部是空数据,而尾部有该分隔符,那么就是直接的去掉,比如,s,s,s,s,,那么长度就是5,即第一个是空数据,而不是没有,即相当于字符串值为""
String replace(char oldChar, charnewChar),使用参数newChar替换此字符串中出现的所有参数oldCharString 
replaceFirst(String regex,String replacement),替换此字符串匹配给定的正则表达式的第一个子字符串String 
replaceAll(String regex,String replacement),将字符串中匹配正则表达式regex的字符串替换成replacement
package com.lagou.task12;

public class StringRegMethodTest {

    public static void main(String[] args) {

        // 1.准备一个字符串对象并打印
        String str1 = "1001,zhangfei,30";
        System.out.println("str1 = " + str1); // 1001,zhangfei,30
        // 2.按照逗号对字符串内容进行切割
        //String[] split(String regex)
        //参数regex为正则表达式,以regex所表示的字符串为分隔符,将字符串拆分成字符串数组
        String[] sArr = str1.split(",");
        for (int i = 0; i < sArr.length; i++) {
            System.out.println("下标为" + i + "的字符串是:" + sArr[i]); // 1001 zhangfei 30
        }

        System.out.println("--------------------------------------------------------------");
        // 3.准备一个字符串内容并进行替换
        String str2 = "我的小名叫大帅哥";
        // 将字符串中所有的字符'我'替换为'你'
        //String replace(char oldChar, charnewChar)
        //使用参数newChar替换此字符串中出现的所有参数oldCharString
        String str3 = str2.replace('我', '你');
        System.out.println("str2 = " + str2); // 我的小名叫大帅哥
        System.out.println("str3 = " + str3); // 你的小名叫大帅哥
        // 将字符串中所有的字符'大'替换为'小'
        String str4 = str3.replace('大', '小');
        System.out.println("str4 = " + str4); // 你的小名叫小帅哥
        // 将字符串中所有的字符'小'替换为'大'
        String str5 = str4.replace('小', '大');
        System.out.println("str5 = " + str5); // 你的大名叫大帅哥

        System.out.println("--------------------------------------------------------------");
        // 4.准备一个字符串进行字符串内容的替换
        String str6 = "123abc456def789ghi";
        // 将第一个数字字符串替换为"#"
        //replaceFirst(String regex,String replacement)
        //替换此字符串匹配给定的正则表达式的第一个子字符串String
        String str7 = str6.replaceFirst("\\d+", "#");
        //从字符串首位置开始,找到首个符合正则表达式的字符串后替换,然后停止
        System.out.println("替换第一个字符串后的结果是:" + str7); // #abc456def789ghi
        // 将所有字母字符串替换为"$$$" $特殊符号,会报错
        //replaceAll(String regex,String replacement)
        //将字符串中匹配正则表达式regex的字符串替换成replacement
        String str8 = str7.replaceAll("[a-z]+", "A");
        //从字符串首位置开始,找到所有符合正则表达式的字符串后替换,然后停止
        System.out.println("str8 = " + str8); // #A456A789A

    }
}

当然,正则表达式有很多,比如:
/*
\.
一般情况下\后面可以随便加,那么就是显示谁,但是有些存在特殊的含义,如\d,这个时候可能需要单纯的d了,具体可以百度
    简单来说,除了他的规则处理外,其他的基本就是直接的对比
    如:
    //这里的处理记得看源码(如System.out.println(a.matches(b));,即matches里面的),你会明白的
    Pattern pattern = Pattern.compile("/springmvc_xie/demo/query");
        System.out.println(pattern);
        Matcher m = pattern.matcher("/demo/query");
        boolean matches = m.matches();
        System.out.println(matches);
    
    */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. HashSet的概述 HashSet是Java集合框架中的一种Set接口的实现类,它基于哈希表实现,可以快速地进行元素查找和插入操作。 2. 创建HashSet对象 可以使用无参构造方法创建一个空的HashSet对象,也可以使用带有集合或数组参数的构造方法创建一个包含初始元素的HashSet对象。 ``` // 创建一个空的HashSet对象 Set<String> set1 = new HashSet<>(); // 创建一个包含初始元素的HashSet对象 Set<String> set2 = new HashSet<>(Arrays.asList("apple", "banana", "orange")); ``` 3. 添加元素 可以使用add方法向HashSet中添加元素,如果元素已经存在,则不会重复添加。 ``` set1.add("apple"); set1.add("banana"); set1.add("orange"); ``` 4. 删除元素 可以使用remove方法从HashSet中删除指定元素,如果元素不存在,则不会进行任何操作。 ``` set1.remove("banana"); ``` 5. 判断元素是否存在 可以使用contains方法判断HashSet中是否包含指定元素。 ``` if (set1.contains("apple")) { // do something } ``` 6. 获取元素个数 可以使用size方法获取HashSet中元素的个数。 ``` int size = set1.size(); ``` 7. 清空集合 可以使用clear方法清空HashSet中的所有元素。 ``` set1.clear(); ``` 8. 遍历集合 可以使用for-each循环或迭代器遍历HashSet中的元素。 ``` // for-each循环 for (String element : set1) { // do something } // 迭代器 Iterator<String> iterator = set1.iterator(); while (iterator.hasNext()) { String element = iterator.next(); // do something } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值