集合
为了保存数目不确定的对象,Java提供了一系列特殊的类,这些类可以存储任意类型(包括数字类型、字符串、对象、类等)的对象,
且长度可以改变,这些类统称为集合。集合类都位于Java.util包中,使用时需导包。
集合按照存储结构可分为单列集合(Collection)和双列集合(Map)
Collectio:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子楼分别是List和Set。其中,List 的特点是元素有序、可重复。Set 的特点是元素无序且不可重复。List 接口的主要实现类有ArrayList(底层封装的是数组)和Linkedlist,Set接口的主要实现类有HashSet 和 TreeSet。
Map:双列集合类的根接口,用于存储具有键(Key)值(Value)映射关系的元素,每个元素都包含一对键值,其中键值不可重复且每个键最多只能映射到一个值,在使用Map集合时可以通过指定的Key找到对应的Value。例如,根据一个学生的学号就可以找到对应的学生。Map接口的主要实现类有HashMap和TreeMap。
Collection接口
Collection是所有单列集合的父接口它定义了单列集合通用的一些方法这些方法可用于操作所有的单列集合。Collection常用方法如下:
add() 向集合中添加一个元素
clear() 删除集合中的所有元素
remove() 删除集合中指定的元素
equals() 判断两个是否相等
isEmpty() 判断集合是否为空
size() 获取该集合元素的个数
在开发中往往很少直接使用Collection接口进行开发,基本上都是使用子接口。
List接口
List接口
List接口继承自Collection接口,是单列集合的一个重要分支。List集合允许出现重复的元素,所有的元素都是以一种线性方式进行存储的。另外List集合还有一个特点就是元素有序,即元素的存入数据和取出数据一致。
List不但继承了Collection接口的全部方法,还增加了一些根据元素索引操作集合的特有方法。List集合常见的方法如下:
add(index,element) 将元素111插入在List集合的index处
get(111) 返回(查看)集合索引111处的元素
set(index,element) 将集合索引index处的元素替换成element对象,并将替换后的元素返回。
ArrayList接口
查找快,删除慢
ArrayList是List接口的一个实现类。可以看作一个长度可变的数组。
ArrayList集合中的大部分元素都是从父类Collection和List继承过来的,其中add()方法和get方法分别用于实现元素的存入和取出。
由于ArrayList集合的底层使用一个数组来保存元素,在增加或删除指定元素时,会创建新的数组,效率比较低,因此不太适合做大量的增加或删除。
Iterator接口
Collection接口与Map接口主要用于存储元素,而Iterator接口主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也称迭代器。
foreach循环
Set接口
Set接口
import java.util.Objects;
public class Student {
String id;
String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return Objects.equals(id, student.id) && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public void setName(String name) {
this.name = name;
}
}
模拟创建用户注册系统
利用Set类,实现【案例6-3】 模拟用户注册系统,实现用户名、密码、确认密码、生日、邮箱、手机号等信息的校验。
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class User {
private static Set<String> registeredUsers = new HashSet<>();
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3578]\\d{9}$");
private static final Pattern EMAIL_PATTERN = Pattern.compile(".*@.*\\..*");
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入用户名:");
String username = scanner.nextLine();
System.out.println("请输入密码:");
String password = scanner.nextLine();
System.out.println("请确认密码:");
String confirmPassword = scanner.nextLine();
if (!password.equals(confirmPassword)) {
System.out.println("密码不匹配,注册失败!");
continue;
}
System.out.println("请输入生日 (格式 yyyy-mm-dd):");
String birthdayStr = scanner.nextLine();
try {
dateFormat.parse(birthdayStr); // 检查日期格式是否正确
} catch (ParseException e) {
System.out.println("生日格式不正确,注册失败!");
continue;
}
System.out.println("请输入手机号 (11位,以13、15、17、18开头):");
String phone = scanner.nextLine();
Matcher phoneMatcher = PHONE_PATTERN.matcher(phone);
if (!phoneMatcher.matches()) {
System.out.println("手机号格式不正确,注册失败!");
continue;
}
System.out.println("请输入邮箱:");
String email = scanner.nextLine();
Matcher emailMatcher = EMAIL_PATTERN.matcher(email);
if (!emailMatcher.matches()) {
System.out.println("邮箱格式不正确,注册失败!");
continue;
}
if (registeredUsers.contains(username)) {
System.out.println("用户名已存在,注册失败!");
} else {
registeredUsers.add(username);
System.out.println("注册成功!");
break; // 或者可以选择继续注册其他用户,这里为了简单直接退出循环
}
}
scanner.close();
}
}