20、javase-API.容器

为了在程序中可以保存数目不确定的对象,Java提供了一系列特殊的类容器。

位于 java.util 包中,使用时必须导包。

容器按照其存储结构可以分为两大类

  • 单列集合Collection
    • List:元素有序、可重复
      • ArrayList
      • LinkedList
    • Set:元素无序,不可重复
      • HashSet
      • TreeSet
  • 双列集合Map,用于存储具有键(Key)、值(Value)映射
    • HashMap
    • TreeMap

一、List 接口及实现类

1、List接口

List接口,位于java.util包,承自Collection接口,用于存储一组有序的元素,并且允许元素重复出现。List接口中的常见方法如下(了解即可):

java 复制代码
void add(Object element)	
    将元素element插入在List集合的尾部
void add(int index,Object element)	
    将元素element插入在List集合的index处
boolean addAll(int index,Collection c)	
    将集合c所包含的所有元素插入到List集合的index处
    
Object get(int index)	
    返回集合索引index处的元素
    
Object remove(int index)	
    删除index索引处的元素
    
Object set(int index, Object element)	
    将索引index处元素替换成element对象,并将替换后的元素返回
    
int indexOf(Object o)	
    返回对象o在List集合中出现的位置索引
    
int lastIndexOf(Object o)	
    返回对象o在List集合中最后一次出现的位置索引
    
List<E> subList(int fromIndex, int toIndex)	
    返回从索引fromIndex(包括)到 toIndex(不包括)处所有元素集合组成的子集合

2、ArrayList实现类

  • ArrayList是 List 接口的数组实现方式。
  • ArrayList在查询元素时速度很快,但在增删元素时效率较低。

1)构造方法

java 复制代码
ArrayList() 
    构造一个初始容量为 10 的空列表;
ArrayList(int initialCapacity)
    构造一个具有指定初始容量的空列表;
ArrayList(Collection<? extends E> c)
    构造一个包含指定集合元素的列表,按照集合迭代器返回元素的顺序。

例如:

java 复制代码
ArrayList<String> strings = new ArrayList<>();

2)添加相关

java 复制代码
boolean add(E e)
    将e附加到此list的末尾;
void add(int index, E element)
    在此list的指定位置前插入e;
boolean addAll(Collection<? extends E> c)
    将C中的所有元素,追加到此list的末尾;
boolean addAll(int index, Collection<? extends E> c)
    将C中的所有元素,插入到此list的index之前;

3)删除相关

java 复制代码
E remove(int index)
    移除此list中指定位置的元素;
boolean remove(Object o)
    从此list中移除第一次出现的指定元素(如果存在);
boolean removeAll(Collection<?> c)
    从此list中移除指定集合中包含的所有元素;

boolean removeIf(Predicate<? super E> filter)
    移除此集合中满足给定谓词的所有元素;
    students.removeIf(student -> {
        return student.age >= 20;
    });

4)修改相关

java 复制代码
E set(int index, E element)
    用指定元素替换此list中指定位置的元素;

5)查询相关

java 复制代码
int size()
    返回此list中的元素数;
boolean isEmpty()
    如果此list不包含任何元素,则返回 true;
boolean contains(Object o)
    如果此list包含指定元素,则返回 true;
E get(int index)
    返回此list中指定位置的元素;
List<E> subList(int fromIndex, int toIndex)
    返回此list中指定的 fromIndex(含)和 toIndex(不含)之间的元素。

3、LinkedList实现类

  • List 接口的双向链表实现方式,LinkedList内部维护了一个双向循环链表,每个元素都使用引用的方式来记录它的前一个元素和后一个元素。
  • 对于元素的增删操作具有很高的效率,但查询效率不高。

LinkedList定义了一些特有的方法如下所示:

java 复制代码
void addFirst(Object o)	
    将指定元素插入此列表的开头;
void addLast(Object o)	
    将指定元素添加到此列表的结尾;
Object getFirst()		
    返回此列表的第一个元素;
Object getLast()		
    返回此列表的最后一个元素;
Object removeFirst()	
    移除并返回此列表的第一个元素;
Object removeLast()		
    移除并返回此列表的最后一个元素;

4、循环迭代

java 复制代码
ArrayList list = new ArrayList(); // 创建ArrayList集合
list.add("张三");                  // 向该集合中添加字符串
list.add("李四");
list.add("王五");
list.add("赵六");

方式1:

java 复制代码
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

方式2:

java 复制代码
for (String element : list) {
    System.out.println(element);
}

方式3:

//适用大量数据的场景 没有取到元素暂时不会占用内存

java 复制代码
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

方式4

stus.forEach(student -> {
	System.out.println(student);
});

二、set接口及实现类

Set 接口概述

Set 是 Java 集合框架中的一个接口,位于java.util包中。它是Collection接口的子接口,用于存储一组无序(无序是指元素的存储顺序和插入顺序无关)且不包含重复元素的集合。Set 接口主要用于确保集合中的元素具有唯一性,常见的实现类有HashSetTreeSet

1、HashSet实现类

基本原理

HashSet 是基于哈希表(Hash Table)实现的。

元素添加(add)

java 复制代码
HashSet<String> hashSet = new HashSet<>();
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("apple");
System.out.println(hashSet);

元素删除(remove)

java 复制代码
hashSet.remove("apple");
System.out.println(hashSet);

元素查找(contains)

java 复制代码
System.out.println(hashSet.contains("banana"));

获取集合大小(size)

java 复制代码
System.out.println(hashSet.size());

HashSet 的元素唯一性原理

当向 HashSet 中添加元素时,首先会调用元素的hashCode方法来获取元素的哈希码,根据哈希码确定元素在哈希表中的存储位置。如果两个元素的哈希码相同,会进一步调用equals方法来判断它们是否真正相等。只有当hashCodeequals方法都表明两个元素相同时,才认为它们是重复元素,不会将新元素添加到集合中。

例如:

java 复制代码
public class Student {
    String sno;
    String sname;

    public Student(String sno, String sname) {
        this.sno = sno;
        this.sname = sname;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(sno, student.sno) && Objects.equals(sname, student.sname);
    }

    @Override
    public int hashCode() {
        return Objects.hash(sno, sname);
    }

    @Override
    public String toString() {
        return "Student{" +
                "sno='" + sno + '\'' +
                ", sname='" + sname + '\'' +
                '}';
    }
}

测试

java 复制代码
class Test {
    public static void main(String[] args) {
        HashSet<Student> students = new HashSet<>();
        students.add(new Student("001", "张三"));
        students.add(new Student("001", "张三"));

        for (Student student : students) {
            System.out.println(student);
        }
    }
}

2、TreeSet实现类

基于红黑树(Red - Black Tree)数据结构实现的。

TreeSet 中的元素是有序的、且不重复的

  • 要么按照元素的自然顺序(如果元素实现了Comparable接口)
  • 要么根据提供的比较器(compareTo)来排序。

1)自然顺序

java 复制代码
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(3);
treeSet.add(1);
treeSet.add(2);
System.out.println(treeSet);

2)自定义排序

根据Comparable接口中compareTo方法的比较结果排序

java 复制代码
public class Student implements Comparable<Student> { //实现Comparable接口
    String sno;
    String sname;

    public Student(String sno, String sname) {
        this.sno = sno;
        this.sname = sname;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sno='" + sno + '\'' +
                ", sname='" + sname + '\'' +
                '}';
    }

    @Override
    public int compareTo(Student o) {  //根据学号排序
        return this.sno.compareTo(o.sno);
    }
}

测试类

java 复制代码
class Test {
    public static void main(String[] args) {
        TreeSet<Student> students = new TreeSet<>();
        students.add(new Student("001", "张三"));
        students.add(new Student("001", "张三"));

        for (Student student : students) {
            System.out.println(student);
        }
    }
}

3)特有方法

java 复制代码
E first()
    返回此集合中当前的第一个(最低)元素;
E last()
    返回此集合中当前的最后一个(最高)元素;
E pollFirst()
    返回【并删除】此集合中当前的第一个(最低)元素;
E pollLast()
  返回【并删除】此集合中当前的最后一个(最高)元素;
SortedSet<E> subSet(E fromElement, E toElement)
    返回此集合的部分视图,其元素范围从 fromElement(含)到 toElement(不含);
SortedSet<E> tailSet(E fromElement)
    返回此集合中元素【大于或等于】 fromElement 的部分的视图;

3、综合练习

用户输入用户名、密码、确认密码、生日(格式为yyyy--mm---dd为正确)、手机号(手机号长度为11位,并且以13、15、17、18为开头的手机号为正确)、邮箱(包含符号"@"为正确)信息之后,判断信息正确后,验证用户是否重复,重复则给出相应提示,如果不重复则注册成功。
案例要求分别使用HashSet和TreeSet实现。

三、Map接口及实现类

1、Map接口

Map接口是一种双列集合,它的每个元素都包含一个键对象Key和值对象Value,键和值对象之间存在一种对应关系,称为映射。从Map集合中访问元素时,只要指定了Key,就能找到对应的Value。

Map接口常用方法

java 复制代码
// 增加
void put(Object key, Object value)	
    将指定的值与此映射中的指定键关联(可选操作);

// 删除
void clear()
    从此map中删除所有映射(可选操作);
V remove(Object key)
    如果存在,则从此map中删除键的映射(可选操作);
boolean remove(Object key, Object value)
    仅当指定键当前映射到指定值时才删除该条目;

// 修改
V replace(K key, V value)
    仅在当前映射到某个值时才替换指定键的条目;
boolean replace(K key, V oldValue, V newValue)
    仅当当前映射到指定值时才替换指定键的条目;

// 查询
int size()
    返回此map中键值对的数量;
V get(Object key)
    返回指定键映射到的值,如果此map不包含键的映射,则返回 null;
V getOrDefault(Object key, V defaultValue)
    返回指定键映射到的值,如果此map不包含键的映射,则返回 defaultValue;
Set<K> keySet()
    返回此map中,包含的【键】的 Set 视图;
Collection<V> values() 
    返回此map中,包含的【值】的 Collection 视图;
Set<Map.Entry<K,V>>entrySet()
    返回此map中,包含的【键和值】的 Set 视图;

// 判断
boolean isEmpty()
    如果此map不包含键值映射,则返回 true;
boolean containsKey(Object key)
    如果此map包含指定键的映射,则返回 true;
boolean containsValue(Object value)
    如果此map将一个或多个键映射到指定值,则返回 true;

2、HashMap实现类

HashMap 是 Java 集合框架中的一个重要类,位于java.util包中。它实现了 Map 接口,用于存储键 - 值(key - value)对。

创建 HashMap

使用无参数构造函数创建一个空的 HashMap

java 复制代码
HashMap<String, Integer> hashMap = new HashMap<>();
System.out.println(hashMap);

通过指定初始容量和负载因子来创建 HashMap。

java 复制代码
// 当前的容器容量是16,负载因子是0.75;
// 16*0.75=12,也就是说,当容量达到了12的时就会执行扩容操作。
// 思考当负载因子为1.0或0.5时会发生什么?
HashMap<String, Integer> hashMap = new HashMap<>(16, 0.75f);
System.out.println(hashMap);

添加键 - 值对(put)

java 复制代码
hashMap.put("Alice", 90);
hashMap.put("Bob", 80);

如果添加的键已经存在于 HashMap 中,新的值会覆盖旧的值

java 复制代码
int oldValue = hashMap.put("Alice", 95);
System.out.println("旧的值为: " + oldValue);
System.out.println(hashMap);

获取值(get)

java 复制代码
System.out.println(hashMap.get("Bob"));

删除键 - 值对(remove)

java 复制代码
hashMap.remove("Bob");

遍历 HashMap 的方式

通过 keySet() 方法获取 HashMap 中所有键,然后遍历键集来获取对应的值。

java 复制代码
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("Alice", 90);
hashMap.put("Bob", 80);
hashMap.put("Charlie", 95);
Set<String> keySet = hashMap.keySet();
for (String key : keySet) {
    System.out.println(key + " : " + hashMap.get(key));
}

通过 entrySet() 方法获取包含所有键 - 值对的集合,每个元素是一个Map.Entry类型,包含键和值。

java 复制代码
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("Alice", 90);
hashMap.put("Bob", 80);
hashMap.put("Charlie", 95);
Set<Map.Entry<String, Integer>> entrySet = hashMap.entrySet();
for (Map.Entry<String, Integer> entry : entrySet) {
    String key = entry.getKey();          // 获取Entry中的键
    Integer value = entry.getValue();     // 获取Entry中的值
    System.out.println(key + ":" + value);
}
maps.forEach((key, value) -> {
System.out.println(key + ":" + value);
});

3、TreeMap实现类

TreeMap 是 Java 集合框架中的一个实现类,位于java.util包中。它实现了Map接口,用于存储键 - 值(key - value)对。和 HashMap 不同,TreeMap 是基于红黑树(Red - Black Tree)这种自平衡二叉查找树的数据结构实现的。

基本使用

自然序

java 复制代码
//创建 TreeMap 对象
TreeMap<Integer, String> treeMap = new TreeMap<>(); 
// 添加
treeMap.put(3, "apple");	
treeMap.put(1, "banana");
treeMap.put(2, "cherry");
// 删除
String removedValue = treeMap.remove(1); 
// 修改
String oldValue = hashMap.replace(2, "香蕉");
// 查询
String value = hashMap.get(2);

自定排序(自定义子类)

相关推荐
旧物有情2 分钟前
蓝桥杯历届真题 #分布式队列 (Java,C++)
java·分布式·蓝桥杯
high20117 分钟前
【Java】-- 利用 jar 命令将配置文件添加到 jar 中
java·pycharm·jar
Xiao5xiao12221 分钟前
java后端对接飞书登陆
java·开发语言·飞书
Xiao Tong33331 分钟前
八大排序算法(Java,便于理解)
java·算法·排序算法
新知图书42 分钟前
Spring MVC简单数据绑定
java·spring·mvc
CURRY30_HJH1 小时前
JAVA 使用apache poi实现EXCEL文件的输出;apache poi实现标题行的第一个字符为红色;EXCEL设置某几个字符为别的颜色
java·apache·excel
疯狂小小小码农1 小时前
C++语言的文件操作
开发语言·后端·golang
莲动渔舟1 小时前
Python自学 - 类进阶(可调用对象)
开发语言·python
梵谷的忧伤1 小时前
两个栈实现队列(D)
java·开发语言·前端·算法
Reese_Cool1 小时前
【Python】Python与C的区别
java·c语言·python