Java-String类&集合ArrayList

简介: Java-String类&集合ArrayList

java.lang.String类代表字符串。
Java程序中所有字符串文字都为此类的对象。

注意:String类首字母大写,类的首字母都大写。
  • 以"xx"形式给出的字符串对象,在字符常量池中存储。
  • 字符串类型,可以定义字符串变量指向字符串对象。
  • string变量每次的修改都是产生并指向了新的字符串对象。
  • 原来的字符串对象都是没有改变的,所以称不可变字符串。

创建字符串

方法一:直接使用 ""创建

String name = "张三";

方法二:使用String()构造器

String name = new String();
使用字符数组:String name = new String(char[] c);

char[] chars={'你','好','世','界'};
String str=new String(chars);
System.out.println(str);//你好世界

使用字节数组:String name = new String(byte[] c);

byte[] bytes = {65, 66, 'C', 'C' + 1};
String str = new String(bytes);
System.out.println(str);//ABCD
两种创造方式的区别
  • ""方式给出的字符串对象,在字符串常量池中储存,而且相同内容只会在其中存储一份。
  • 通过构造器new对象,每new一次都会产生一个新对象,放在堆内存中。

image.png

举个例子
//创建了两个对象
String s1 = new String("abc");
//创建了0个对象
String s2 = "abc";
//输出false
System.out.println(s1 == s2);

第一行代码,分别在字符串常量池和堆区创建了一个"abc"对象。
第二行代码,指向了字符串常量池中已有的"abc"对象。
第三行代码,两个String对象存储的地址不一样,输出false

Java存在编译优化机制

String s1 = "abc";
String s2 = "ab";
String s3 = s2 + "c";
String s4 = "ab" + "c";
//false
System.out.println(s1 == s3);
//true
System.out.println(s1 == s4);

程序在编译阶段,"ab"+"c"会直接转成"abc"。

字符串内容比较

直接使用 ==会出现问题

直接使用==对比的是字符串对象存储的地址。

//正确的用户名密码
String name = "name";
String password = "password";
//用户输入用户名密码
Scanner sc = new Scanner(System.in);
String tmpname = sc.next();
String tmppsword = sc.next();
//判断用户输入是否正确
System.out.println(name == tmpname);//false
System.out.println(password == tmppsword);//false
比较内容要用 .equals()方法。
//正确的用户名密码
String name = "name";
String password = "password";
//用户输入用户名密码
Scanner sc = new Scanner(System.in);
String tmpname = sc.next();
String tmppsword = sc.next();
//判断用户输入是否正确
System.out.println(name.equals(tmpname));
System.out.println(password.equals(tmppsword));

.equalsIgnoreCase()可以忽略大小写比较,常用于对比验证码。

常用API

image.png

通过.lenth()和.charAt()遍历字符串

获取字符串长度

.lenth()

获取某个索引位置处的字符

.charAt()

String str="你好世界";
for (int i=0;i<str.length();i++)
{
    System.out.println(str.charAt(i));
}

将字符串转化为字符数组

Java中字符数组可以直接输出,也可以用下标访问输出。

String str = "你好世界";
char[] chars = str.toCharArray();
System.out.println(chars);
for (int i = 0; i < str.length(); i++) {
    System.out.println(chars[i]);
}

截取内容,包前不包后

很多语言的方法,用到区间时,都是:包前不包后

String str = "Java是世界上最好的编程语言";
//Java
System.out.println(str.substring(0,4));
char[] chars=str.substring(4).toCharArray();
//是世界上最好的编程语言
System.out.println(chars);

替换关键词

String str = "金三胖是最厉害的,金三胖胖胖的,我好喜欢金三胖";
String str1 = str.replace("金三胖", "XX");
System.out.println(str1);

判断是否包含关键词

String str = "金三胖是最厉害的,金三胖胖胖的,我好喜欢金三胖";
System.out.println(str.contains("金三胖"));//true

判断以什么开始

String str = "金三胖是最厉害的,金三胖胖胖的,我好喜欢金三胖";
System.out.println(str.startsWith("金三胖"));//true
System.out.println(str.startsWith("金二胖"));//false

分割字符串,以字符串数组返回

String name = "kunkun,蔡徐坤,ikun";
String[] names = name.split(",");
for (String str : names) {
    System.out.println(str);
}

String案例

验证码

  • 定义一个String类型的变量,存储a-z,A-Z,0-9之间的全部字符。
  • 循环五次,随机一个范围内的索引,获取对应字符连接起来即可。
//定义可能出现的字符信息
String datas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//循环五次,每次生成一个随机的索引,提取对应的字符连接起来
String code = "";
Random rd = new Random();
for (int i = 0; i < 5; i++) {
    //随机一个索引
    int index = rd.nextInt(datas.length());
    code += datas.charAt(index);
}
//输出字符串变量
System.out.println(code);

模拟用户登录功能

  • 系统后台定义好正确的登录名称、密码。
  • 使用循环控制三次,让用户输入正确的登录名和密码,判断是否登录成功,登陆成功则不再进行登录,登陆失败则给出提示,并让用户继续登录。
//定义正确的用户名密码
String okLoginName = "Caixukun";
String okPassword = "ctraplq";
//定义一个循环,让用户登录
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
    System.out.println("请输入用户名");
    String loginName = sc.next();
    System.out.println("请输入密码");
    String password = sc.next();
    //判断登陆是否成功
    if (loginName.equals(okLoginName)) {
        //判断密码是否正确
        if (password.equals(okPassword)) {
            System.out.println("登陆成功");
            break;
        } else
            System.out.println("密码错误,还剩" + (3 - i) + "次机会");
    } else
        System.out.println("用户名错误");
}

手机号码屏蔽

以字符串形式从键盘接受一个手机号,将中间四位号码屏蔽,最终效果为:
183****3572
分析:

  1. 键盘录入一个字符串。
  2. 截取字符串前三位,截取字符串后四位。
  3. 将截取后的两个字符串,中间加上**进行拼接,输出结果即可。
//键盘录入一个手机号码
Scanner sc = new Scanner(System.in);
System.out.println("请输入手机号码");
String tel = sc.next();
//截取代码前三位、后四位
String before = tel.substring(0, 3);
String after = tel.substring(7);
String s = before + "****" + after;
System.out.println(s);

集合ArrayList

集合与数组类似,是一种容器,用于装数据。
数组的特点:

  • 数组定义完成并启动后,类型确定,长度固定。
  • 问题:在个数不确定,且要进行增删数据操作时,数组是不太合适的。

集合的特点:

  • 集合的大小不固定,启动后可以动态变化,类型也可以选择不固定。
  • 集合非常适合做元素个数不确定,且要进行增删操作的业务场景。
  • 集合提供了许多丰富好用的功能,而数组的功能很单一。

ArrayList集合的对象添加与获取

ArrayList是集合的一种,它支持索引。
.add()返回值为boolean,一般不会添加失败,因此我们一般不会注意它的返回值。
System.out.println(list);会直接输出集合内容,而不是地址

//创建ArrayList集合对象
ArrayList list = new ArrayList();
//添加数据
list.add("java");
list.add(1);
list.add(2.5);
list.add(false);
System.out.println(list.add('可'));
System.out.println(list);//[java, 1, 2.5, false, 可]
//在指定索引位置插入元素
list.add(1, "插入");
System.out.println(list);//[java, 插入, 1, 2.5, false, 可]

泛型概述

ArrayList<E>就是一个泛型,可以在编译阶段约束集合对象,只能操作某种数据类型。
使用泛型:<数据类型>
举例:

  • ArrayList<String>:此集合只能操作字符串类型的元素。
  • ArrayList<Integer>:此集合只能操作整数类型的元素。

注意:集合中只能存储引用类型,不支持基本数据类型。ArrayList<Integer>不能填<int>
代码规范:使用泛型来定义和使用集合

ArrayList<String> list = new ArrayList<String>();
//JDK1.7开始,泛型后面的类型声明可以不写
ArrayList<String> list1 = new ArrayList<>();
//使用Object存储所有数据类型
ArrayList<Object> list2 = new ArrayList<>();

ArrayList常用API、遍历

  • .get()//获取某个索引位置处的元素值
  • .size()//获取集合大小
  • .remove()//删除某个索引位置处的值,并返回被删除的值
  • .set()//修改某个索引位置的值,会返回修改前的值
ArrayList<Integer> list = new ArrayList<>();
list.add(2);
list.add(4);
list.add(6);
list.add(2);
//获取某个索引位置处的元素值
System.out.println(list.get(1));
//获取集合大小
System.out.println(list.size());
//完成集合的遍历
for (int i = 0; i < list.size(); i++) {
    System.out.print(list.get(i) + " ");
}
//删除某个索引位置处的值,并返回被删除的值
System.out.println("\n" + list.remove(1));
System.out.println(list);
//直接删除元素值,删除成功返回true,失败返回false
//需要使用Integer,否则是删除索引
System.out.println(list.remove((Integer) 2));
System.out.println(list);
//修改某个索引位置的值,会返回修改前的值
System.out.println(list.set(0, 2));
System.out.println(list);

ArrayList存储自定义数据类型的对象

image.png

Movie m1 = new Movie("流浪地球", 9.0, "吴京");
//创建一个Movie类型的ArrayList,存储电影对象
ArrayList<Movie> arrayList = new ArrayList<>();
arrayList.add(m1);
arrayList.add(new Movie("熊出没", 9.9, "光头强"));
//遍历每一个对象,访问信息
//直接输出自定义数据类型,结果是地址
System.out.println(arrayList);
for (int i = 0; i < arrayList.size(); i++) {
    System.out.println(arrayList.get(i).getName() + " " + arrayList.get(i).getScore() + " " + arrayList.get(i).getActor());
}
Movie类文件:
public class Movie {
    private String name;
    private double score;
    private String actor;

    public Movie(String name, double score, String actor) {
        this.name = name;
        this.score = score;
        this.actor = actor;
    }

    public String getName() {
        return name;
    }

    public double getScore() {
        return score;
    }

    public String getActor() {
        return actor;
    }
}

学生信息系统的数据搜索

需求:

  • 后台程序需要存储学生信息并展示,然后要提供按照学号搜索的功能。

分析:

  • 定义Student类,定义ArrayList存储学生对象信息,并遍历展示出来。
  • 提供一个方法,可以接收ArrayList集合,和要搜索的学号,返回搜索到的学生对象信息,并展示。
  • 使用死循环,让用户可以不停的搜索。
Student类
public class Student {
    private String studyNumber;
    private String name;
    private int age;

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

    public String getStudyNumber() {
        return studyNumber;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}
Main类
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        //创建集合存储学生对象,创建学生对象封装学生信息
        ArrayList<Student> studentArrayList = new ArrayList<>();
        studentArrayList.add(new Student("001", "张三", 10));
        studentArrayList.add(new Student("002", "李四", 12));
        studentArrayList.add(new Student("003", "王五", 11));
        //遍历学生信息展示
        for (int i = 0; i < studentArrayList.size(); i++) {
            Student tmp = studentArrayList.get(i);
            System.out.println(tmp.getStudyNumber() + "\t" + tmp.getName() + "\t" + tmp.getAge());
        }
        //定义方法,完成按照学号搜索的功能
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入学号");
            String studyNumber = sc.next();
            //调用方法查询
            Student student = getStudentById(studentArrayList, studyNumber);
            if (student == null) {
                System.out.println("查无此人");
            } else System.out.println(student.getStudyNumber() + "\t" + student.getName() + "\t" + student.getAge());
        }
    }

    /**
     * 根据学生学号,查询学生对象返回
     *
     * @param a             存储全部学生对象的集合
     * @param studentNumber 搜索的学生的学号
     * @return 学生对象 | null
     */
    public static Student getStudentById(ArrayList<Student> a, String studentNumber) {
        //遍历全部学生对象
        for (int i = 0; i < a.size(); i++) {
            //询问当前遍历的这个学生对象的学号,是否是我们要找的学号
            Student s = a.get(i);
            if (s.getStudyNumber().equals(studentNumber)) {
                //找到了
                return s;
            }
        }
        //没找到
        return null;
    }
}
目录
相关文章
|
10天前
|
Java 索引 容器
Java ArrayList扩容的原理
Java 的 `ArrayList` 是基于数组实现的动态集合。初始时,`ArrayList` 底层创建一个空数组 `elementData`,并设置 `size` 为 0。当首次添加元素时,会调用 `grow` 方法将数组扩容至默认容量 10。之后每次添加元素时,如果当前数组已满,则会再次调用 `grow` 方法进行扩容。扩容规则为:首次扩容至 10,后续扩容至原数组长度的 1.5 倍或根据实际需求扩容。例如,当需要一次性添加 100 个元素时,会直接扩容至 110 而不是 15。
Java ArrayList扩容的原理
|
14天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
37 17
|
6天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
14 2
|
6天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
11天前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
10天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
50 4
|
14天前
|
存储 Java 索引
Java中的数据结构:ArrayList和LinkedList的比较
【10月更文挑战第28天】在Java编程世界中,数据结构是构建复杂程序的基石。本文将深入探讨两种常用的数据结构:ArrayList和LinkedList,通过直观的比喻和实例分析,揭示它们各自的优势与局限,帮助你在面对不同的编程挑战时做出明智的选择。
|
11天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
26 2
|
11天前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
11天前
|
Java 开发者