一、API介绍和帮助文档的使用

API(ApplicationProgrammingInterface):应用程序编程接口 就是别人写好的一些类,给咱们程序员直接拿去调用即可解决问题的

在线帮助文档

Overviewhttps://www.runoob.com/manual/jdk11api/index.html

二、String类

1、特点

有双引号就有一个字符串对象

package com.itheima.string;
​
public class StringDemo1 {
    /*
        String类的特点:
            1. Java程序中的所有字符串文字(例如"abc" )都是String类的对象
            2. String是不可改变的, 它们的值在创建后无法更改
                    - 想要更改, 需要使用新的对象进行替换.
            3. String虽然不可改变, 但是可以被共享操作.
​
                    字符串常量池(StringTable): 当我们使用双引号创建字符串对象的时候.
                                                会检查该数据在常量池中是否存在
                                                不存在: 创建新的
                                                存在: 不会创建新的对象, 复用已有的.
     */
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
​
        System.out.println(s1 == s2);
    }
}

2、常见的构造方法

package com.itheima.string;
​
public class StringDemo2 {
    /*
        String类的构造方法:
            public String() : 创建空白字符串,不含任何内容
            public String(char[] chs) : 根据字符数组,创建字符串对象
            public String(String original) : 根据传入的字符串,创建字符串对象
​
            问题: 两种创建字符串对象的方式, 有什么区别?
            回答:
                    1. 双引号直接创建: 数据在常量池中存储
                    2. 构造方法创建: 会在堆内存开辟独立的内存空间.
     */
    public static void main(String[] args) {
        // 创建空白字符串,不含任何内容
        String s1 = new String();
        System.out.println(s1);
​
        // 根据字符数组,创建字符串对象
        char[] chs = {'a', 'b', 'c'};
        String s2 = new String(chs);
        System.out.println(s2);
​
        // 根据传入的字符串,创建字符串对象
        String s3 = new String("abc");//创建了两个字符串对象
        System.out.println(s3);
​
        String s4 = "abc";
    }
}

3、面试题

(1)对字符串常量池的理解

image-20260630192524095

new出来的字符串类型和引号的字符串类型的区别:

new出来的需要新开辟堆内存,引号则放在字符串常量池

image-20260630193714903

(2)字符串加号拼接

创建字符串缓冲区

调用添加方法拼接成StringBuilder类型的,再用toString方法转换成字符串类型

image-20260630194202949

(3)字面量优化机制的拼接

package com.itheima.string;
​
public class StringDemo3 {
    public static void main(String[] args) {
        byte b = 3 + 4;                     //在javac字节码文件中, byte b = 7;
        System.out.println(b);
​
        String s1 = "abc";
        String s2 = "a" + "b" + "c";        //在javac字节码文件中, String s2 = "abc";
        System.out.println(s1 == s2);
    }
}

4、String用于比较的方法

public bool eanequals方法(要比较的字符串)
//完全一样结果才是true,否则为false
public boolean equalslgnoreCase(要比较的字符串)
//忽略大小写的比较

(1)两个方法的实现

package com.itheima.string;
​
public class StringMethodDemo1 {
    /*
        String类用于比较的方法
        
            public boolean equals方法(要比较的字符串)             完全一样结果才是true, 否则为false
            public boolean equalsIgnoreCase(要比较的字符串)        忽略大小写的比较
     */
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = new String("abc");
​
        System.out.println(s1 == s2);       // false
        System.out.println(s1.equals(s2));  // true
​
        String s3 = "ABC";
        System.out.println(s1.equals(s3));  // false
        System.out.println(s1.equalsIgnoreCase(s3));    // true
    }
}

(2)案例

package com.itheima.test;
​
import java.util.Scanner;
​
public class StringTest1 {
    /*
        需求:已知正确的用户名和密码,请用程序实现模拟用户登录。
                总共给三次机会,登录之后,给出相应的提示
     */
    public static void main(String[] args) {
        // 1. 定义两个字符串变量, 模拟数据库中存在的数据
        String username = "admin";
        String password = "1234";
​
        // 2. 键盘录入用户名和密码
        Scanner sc = new Scanner(System.in);
​
        for (int i = 1; i <= 3; i++) {
            System.out.println("请输入用户名和密码: ");
            String inputUsername = sc.next();
            String inputPassword = sc.next();
​
            // 3. 和正确的用户名密码进行比对
            if (username.equals(inputUsername) && password.equals(inputPassword)) {
                System.out.println("登录成功");
                break;
            } else {
                if (i == 3) {
                    System.out.println("明儿再来吧!");
                } else {
                    System.out.println("登录失败, 您还剩余" + (3 - i) + "次机会");
                }
            }
        }
    }
}

5、和遍历有关的方法

public char[] toCharArray O
//将字符串转换为字符数组
public char chatAt (int index)//根据索引找字符
publicintlength();//返回字符串的长度

(1)方法实现

package com.itheima.string;
​
public class StringMethodDemo2 {
    /*
        String类中和遍历有关的方法
            public char[]  toCharArray()    将字符串转换为字符数组
            public char chatAt(int index)  根据索引找字符
            public int length() : 返回字符串的长度
     */
    public static void main(String[] args) {
​
        String s = "itheima";
​
        // 将字符串转换为字符数组
        char[] charArray = s.toCharArray();
​
        for (int i = 0; i < charArray.length; i++) {
            System.out.println(charArray[i]);
        }
​
        System.out.println("---------------------------------");
​
        // 根据索引找字符
        for (int i = 0; i < s.length(); i++) {
            // i = 0 1 2 3 4 5 6
            char c = s.charAt(i);
            System.out.println(c);
        }
    }
}

(2)案例

package com.itheima.test;
​
import java.util.Scanner;
​
public class StringTest2 {
    /*
        需求 : 键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数
        (不考虑其他字符)
​
        例如 :  aAb3&c2B*4CD1
​
        小写字母 : 3个
        大写字母 : 4个
        数字字母 : 4个
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入: ");
        String content = sc.next();
​
        // 1. 定义三个计数器变量
        int smallCount = 0;
        int bigCount = 0;
        int numCount = 0;
        // 2. 将字符串转换为字符数组
        char[] arr = content.toCharArray();
        // 3. 遍历字符数组, 获取每一个字符
        for (int i = 0; i < arr.length; i++) {
            // 4. 判断当前字符是哪一种
            if (arr[i] >= 'a' && arr[i] <= 'z') {
                // 5. 对应的计数器自增
                smallCount++;
            } else if (arr[i] >= 'A' && arr[i] <= 'Z') {
                bigCount++;
            } else if (arr[i] >= '0' && arr[i] <= '9') {
                numCount++;
            }
        }
        // 6. 遍历结束后, 打印计数器的值
        System.out.println("小写字母: " + smallCount);
        System.out.println("大写字母: " + bigCount);
        System.out.println("数字字符: " + numCount);
    }
}

6、截取方法

package com.itheima.string;

public class StringMethodDemo3 {
    /*
        String类中的截取方法
            public String substring(int beginIndex)     截取到末尾
            
            public String substring(int beginIndex, int endIndex)  根据指定的索引截取字符串
            
注意点:包头不包尾,包左不包右
     */
    public static void main(String[] args) {
        String s = "itheima";

        String result1 = s.substring(0, 2);
        String result2 = s.substring(2);

        System.out.println(result1);
        System.out.println(result2);
    }
}

(1)案例

package com.itheima.test;
​
import java.util.Scanner;
​
public class StringTest3 {
    /*
        需求:以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽
        最终效果为:156****1234
​
        1. 截取前三位        156
        2. 截取后四位        1234
        3. 拼接 ****        156 + "****" + 1234
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入手机号: ");
        String tel = sc.next();
​
        // 1. 截取前三位
        String start = tel.substring(0, 3);
        // 2. 截取后四位
        String end = tel.substring(7);
        // 3. 拼接
        System.out.println(start + "****" + end);
    }
}

7、替换方法

String类的替换方法

  public String replace(旧值,新值) 替换

        注意点:返回值才是替换之后的结果

需求:键盘录入一个字符串, 如果字符串中包含TMD, 则使用 *** 替换

8、String类的切割方法

public String[] split(String regex) 根据传入的字符串作为规则进行切割

将切割后的内容存入字符串数组中,并将字符串数组返回

package com.itheima.string;
​
import java.util.Scanner;
​
public class StringMethodDemo4 {
    /*
        1. String类的替换方法
                public String replace(旧值,新值) 替换
                注意点:返回值才是替换之后的结果
                需求:键盘录入一个字符串, 如果字符串中包含TMD, 则使用 *** 替换
​
        2. String类的切割方法
                public String[] split(String regex) :根据传入的字符串作为规则进行切割
                将切割后的内容存入字符串数组中,并将字符串数组返回
     */
    public static void main(String[] args) {
        String s = "192+168+10+20";
        //"\\"为转义字符, 表示普通字符
        String[] arr = s.split("\\+");
​
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
​
    }
​
    private static void method() {
        String s = "itheima";
        String result = s.replace("heima", "baima");
        System.out.println(result);
​
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入: ");
        String msg = sc.next();
        msg = msg.replace("TMD", "***");
        System.out.println(msg);
    }
}

三、StringBuilder

 package com.itheima.stringbuilder;
 
 public class StringBuilderDemo3 {
     /*
         StringBuilder的构造方法:
 
             1. public StringBuilder() : 创建一个空白的字符串缓冲区
             2. public StringBuilder(String str) : 创建一个字符串缓冲区, 并指定初始值.
 
         StringBuilder的成员方法:
 
             1. public StringBuilder append(任意类型): 添加数据到缓冲区的尾部, 返回对象自己
             2. public StringBuilder reverse() : 反转缓冲区的内容
             3. public int length() : 获取长度
             4. public String toString() : 转换为String类型
      */
     public static void main(String[] args) {
         StringBuilder sb = new StringBuilder();
 
         // 链式编程: 如果方法的返回值是对象, 就可以继续向下调用方法
         sb.append("红色").append("蓝色").append("绿色");
         System.out.println(sb);
         // 将缓冲区中的内容转换为字符串, 并使用split方法进行切割
         String[] arr = sb.toString().split("色");
 
         for (int i = 0; i < arr.length; i++) {
             System.out.println(arr[i]);
         }
 
     }
 
     private static void method() {
         // 创建一个空白的字符串缓冲区
         StringBuilder sb1 = new StringBuilder();
         System.out.println(sb1);
 
         // 创建一个字符串缓冲区, 并指定初始值.
         StringBuilder sb2 = new StringBuilder("abc");
         System.out.println(sb2);
     }
 }

1、初体验

package com.itheima.stringbuilder;

public class StringBuilderDemo1 {
    /*
        StringBuilder可以提高字符串的操作效率.

                String, 10万次拼接耗时: 2550毫秒
                StringBuilder, 10万次拼接耗时: 8毫秒
     */
    public static void main(String[] args) {

        long start = System.currentTimeMillis();

        StringBuilder sb = new StringBuilder();

        for(int i = 1; i <= 100000; i++){
            sb.append(i);
        }

        System.out.println(sb);

        long end = System.currentTimeMillis();

        System.out.println(end - start);
    }

    private static void method() {
        // 1970年1月1日 0时0分0秒到现在所经历的毫秒值
        long start = System.currentTimeMillis();

        String s = "";

        for(int i = 1; i <= 100000; i++){
            s += i;
        }

        System.out.println(s);

        long end = System.currentTimeMillis();

        System.out.println(end - start);
    }
}

2、StringBuilder的特点

StringBuilder是字符串的缓冲区, 可以将其理解为是一种容器.

容器可以添加任意数据类型, 但是只要进入这个容器, 全部变成字符串.

StringBuilder是一个可变的字符序列.

package com.itheima.stringbuilder;
​
public class StringBuilderDemo2 {
    /*
        StringBuilder是字符串的缓冲区, 可以将其理解为是一种容器.
                    - 容器可以添加任意数据类型, 但是只要进入这个容器, 全部变成字符串.
​
        StringBuilder是一个可变的字符序列.
     */
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
​
        sb.append("红色");
        System.out.println(sb);
​
        sb.append("蓝色");
        System.out.println(sb);
​
        sb.append("绿色");
        System.out.println(sb);
    }
​
    private static void method() {
        StringBuilder sb = new StringBuilder();
​
        sb.append(10);
        sb.append('a');
        sb.append(12.3);
        sb.append(false);
        sb.append("你好");
​
        System.out.println(sb);
    }
}

3、构造方法

(1)StringBuilder的构造方法

    1. public StringBuilder() : 创建一个空白的字符串缓冲区
    2. public StringBuilder(String str) : 创建一个字符串缓冲区, 并指定初始值.

(2)StringBuilder的成员方法

1. public StringBuilder append(任意类型): 添加数据到缓冲区的尾部, 返回对象自己
2. public StringBuilder reverse() : 反转缓冲区的内容
3. public int length() : 获取长度
4. public String toString() : 转换为String类型

4、案例:回文字符串

package com.itheima.test;
​
import java.util.Scanner;
​
public class StringBuilderTest1 {
    /*
        需求:键盘接受一个字符串,程序判断出该字符串是否是回文字符串,并在控制台打印是或不是
        回文字符串:123321、111
        非回文字符串:123123
​
        思路: 对接收到的字符串反转, 如果反转后的字符串, 和原字符串相同, 就是回文字符串
​
        String --- StringBuilder 的转换.
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入: ");
        String content = sc.next();
​
        // 将String转换为StringBuilder调用内部的反转方法.
        StringBuilder sb = new StringBuilder(content);
        sb.reverse();
​
        // 判断是否是回文字符串
        // content: String类型
        // sb: StringBuilder类型
        if (content.equals(sb.toString())) {
            System.out.println("是");
        } else {
            System.out.println("不是");
        }
    }
}

5、拼接指定格式字符串

拼接频率高的话可以用StringBuilder

package com.itheima.test;

public class StringBuilderTest2 {
    /*
        需求:定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回。
          调用该方法,并在控制台输出结果。
          例如:数组为int[] arr = {1,2,3};
          执行方法后的输出结果为:[1, 2, 3]
     */
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};

        System.out.println(arrayToString(arr));
    }

    public static String arrayToString(int[] arr) {

        if (arr == null || arr.length == 0) {
            return "[]";
        }

        // 创建StringBuilder对象, 用于拼接操作
        StringBuilder sb = new StringBuilder("[");

        // 遍历数组, 取出每一个元素 (排除最后一个)
        for (int i = 0; i < arr.length - 1; i++) {
            sb.append(arr[i]).append(", ");
        }

        // 单独添加最后一个元素, 拼接 ]
        sb.append(arr[arr.length - 1]).append("]");

        return sb.toString();
    }
}

6、StringBuilder的原理和StringBuffer

String类型的每次拼接都要新开辟一次内存空间

image-20260630234151650

StringBuilder无需开辟内存

image-20260630234302373

StringBuilder线程不安全,效率高

StringBuffer线程安全,效率低

二者功能相同

四、集合基础

1、ArrayList长度可变原理

image-20260701110523362

2、集合和数组的使用选择

数组:存储的元素个数固定不变

集合:存储的元素个数经常发生改

3、创建集合

方案1

ArrayList list = new ArrayList();
list.a

方案2:加上尖括号(泛型)

//只能存储
ArrayList<String>list = new ArrayList<>();
list.add(1);
ilist.add(12.3);
list.add('a');
ilist.add("abc");
list.add(false);
package com.itheima.arraylist;
​
import java.util.ArrayList;
​
public class ArrayListDemo1 {
    /*
        集合容器创建
​
        方案1: ArrayList list = new ArrayList();
                    可以存储任意数据类型, 不严谨
​
        方案2: ArrayList<String> list = new ArrayList<>();
                    使用泛型技术, 限制集合中元素的数据类型, 推荐方案.
​
        泛型的细节: 只能编写引用数据类型, 如果要存储 int, double, float... 需要使用包装类.String使用String即可
​
                        byte            Byte
                        short           Short
                        int             Integer     ***
                        long            Long
                        float           Float
                        double          Double
                        boolean         Boolean
                        char            Character   ***
     */
    public static void main(String[] args) {
        // 1. 创建集合容器, 存储 张三, 李四, 王五
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张三");
        list1.add("李四");
        list1.add("王五");
        // 2. 创建集合容器, 存储 11.1 22.2 33.3
        ArrayList<Double> list2 = new ArrayList<>();
        list2.add(11.1);
        list2.add(22.2);
        list2.add(33.3);
​
        System.out.println(list1);
        System.out.println(list2);
    }
}

集合在创建的时候如果不加泛型<>添加数据的时候可以是任意类型

4、建议创建的时候加入泛型,保证数据的严谨和规范

JDK7版本开始,右侧<>中可以省略类型

4、集合常用成员方法(增删改查操作)

API文档中的E代表的是根据泛型匹配的

package com.itheima.arraylist;

import java.util.ArrayList;

public class ArrayListDemo2 {
    /*
        ArrayList常用成员方法:

        1. 增
                boolean add(E e): 将指定的元素追加到此列表的末尾
                void add(int index, E element): 将指定元素插入此列表中的指定位置
        2. 删
                E remove(int index): 删除此列表中指定位置的元素
                boolean remove(Object o): 从该列表中删除指定元素的第一个匹配项(如果存在)
        3. 改
                E set(int index, E element): 用指定的元素替换此列表中指定位置的元素
        4. 查
                E get(int index): 返回此列表中指定位置的元素
                int size(): 返回此列表中的元素数
     */
    public static void main(String[] args) {
        addMethod();
        deleteMethod();
        updateMethod();
        getMethod();
    }

    private static void getMethod() {
        ArrayList<String> list = new ArrayList<>();

        list.add("张三");
        list.add("李四");
        list.add("王五");

        String s = list.get(2);
        System.out.println(list.size());
    }

    private static void updateMethod() {
        ArrayList<String> list = new ArrayList<>();

        list.set(1,"赵四");//用指定的元素替换此列表中指定位置的元素
    }

    private static void deleteMethod() {
        ArrayList<String> list = new ArrayList<>();

        list.remove("李四");//从该列表中删除指定元素的第一个匹配项(如果存在)

    }

    private static void addMethod() {
        ArrayList<String> list = new ArrayList<>();

        list.add("张三");//返回的值是boolean,不是对象,所以不能链式编程
        list.add("李四");//将指定的元素追加到此列表的末尾
        list.add("王五");

        list.set(1, "赵四");//将指定元素插入此列表中的指定位置

    }
}

5、集合练习

案例1:存储字符串并遍历

package com.itheima.test;

import java.util.ArrayList;

public class ArrayListTest1 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("张三");
        list.add("上官玉米");
        list.add("李四");
        list.add("诸葛钢铁");
        list.add("王五");

        // 集合遍历的场景: 如果要实现的需求, 需要操作到集合中的每一个元素.
        for (int i = 0; i < list.size(); i++) {
            String name = list.get(i);
            if (name.length() == 4) {
                System.out.println(name);
            }
        }

    }
}

案例2:存储学生对象并遍历

package com.itheima.test;
​
import com.itheima.pojo.Student;
​
import java.util.ArrayList;
​
public class ArrayListTest2 {
    /*
        需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
     */
    public static void main(String[] args) {
        Student stu1 = new Student("张三", 23);
        Student stu2 = new Student("李四", 14);
        Student stu3 = new Student("王五", 15);
​
        ArrayList<Student> list = new ArrayList<>();
        list.add(stu1);
        list.add(stu2);
        list.add(stu3);
​
        for (int i = 0; i < list.size(); i++) {
            // 从集合中取出[每一个]学生对象
            Student stu = list.get(i);
            // 获取每一个学生对象的年龄, 进行判断.
            if (stu.getAge() < 18) {
                System.out.println(stu);
            }
        }
    }
}

案例3:键盘录入数据到集合

package com.itheima.test;
​
import com.itheima.pojo.Student;
​
import java.util.ArrayList;
import java.util.Scanner;
​
public class ArrayListTest3 {
    /*
        需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
                  学生的姓名和年龄来自于键盘录入
     */
    public static void main(String[] args) {
​
        ArrayList<Student> list = new ArrayList<>();
​
        for (int i = 1; i <= 3; i++) {
            System.out.println("第" + i + "个: ");
            addStudent(list);
        }
​
        // 遍历集合, 取出学生对象, 并打印学生信息
        for (int i = 0; i < list.size(); i++) {
            Student stu = list.get(i);
            System.out.println(stu);
        }
​
    }
​
    private static void addStudent(ArrayList<Student> list) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入姓名: ");
        String name = sc.next();
        System.out.println("请输入年龄: ");
        int age = sc.nextInt();
​
        // 将学生的姓名和年龄, 封装为学生对象
        Student stu = new Student(name, age);
​
        // 将学生对象, 存入集合
        list.add(stu);
    }
}

image-20260701122808218

案例4:遍历过程中删除元素

package com.itheima.test;
​
import java.util.ArrayList;
​
public class ArrayListTest4 {
    /*
        需求:创建一个存储String的集合,内部存储(test,张三,李四,test,test)字符串
                删除所有的test字符串,删除后,将集合剩余元素打印在控制台
     */
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("test");
        list.add("张三");
        list.add("李四");
        list.add("test");
        list.add("test");
​
        for (int i = list.size() - 1; i >= 0; i--) {//倒着删可以完美解决问题
            String s = list.get(i);
            if("test".equals(s)){
                list.remove(i);//删除后元素会整体向前移动
            }
        }
​
        System.out.println(list);
    }
}

案例5:筛选数据到新集合

package com.itheima.test;
​
import com.itheima.pojo.Student;
​
import java.util.ArrayList;
​
public class ArrayListTest5 {
    /*
        需求:定义一个方法,方法接收一个集合对象(泛型为Student)
                方法内部将年龄低于18的学生对象找出
                并存入新集合对象,方法返回新集合
     */
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student("张三", 23));
        list.add(new Student("李四", 14));
        list.add(new Student("王五", 15));
​
        ArrayList<Student> result = filterList(list);
​
        for (int i = 0; i < result.size(); i++) {
            Student stu = result.get(i);
            System.out.println(stu);
        }
    }
​
    private static ArrayList<Student> filterList(ArrayList<Student> list) {
        // 1. 创建新集合
        ArrayList<Student> result = new ArrayList<>();
        // 2. 遍历原集合, 取出每一个学生对象
        for (int i = 0; i < list.size(); i++) {
            Student stu = list.get(i);
            // 3. 判断该学生的年龄, 是否低于18岁
            if(stu.getAge() < 18){
                // 4. 存入新集合
                result.add(stu);
            }
        }
        // 5. 返回新集合
        return result;
    }
​
​
}