凉城旧巷
Python从入门到自闭,Java从自闭到放弃,数据库从删库到跑路,Linux从rm -rf到完犊子!!!
posts - 315,comments - 20,views - 38万

集合

一、集合分类及关系

Java的java.util包主要提供了以下三种类型的集合:

  • List:一种有序元素可重复列表的集合,例如,按索引排列的StudentList
  • Set:一种无序元素不能重复的集合,例如,所有无重复名称的StudentSet
  • Map:一种通过键值(key-value)查找的映射表集合,例如,根据Studentname查找对应StudentMap

Java标准库自带的java.util包提供了集合类:Collection,它是除Map外所有其他集合类的根接口

二、集合的特点

  • 一是实现了接口和实现类相分离,例如,有序表的接口是List,具体的实现类有ArrayListLinkedList

  • 二是支持泛型,我们可以限制在一个集合中只能放入同一种数据类型的元素

    ArrayList<String> al = new ArrayList<String>();
    
  • 三是访问集合总是通过统一的方式——迭代器(Iterator)来实现

三、List接口

1、接口方法

List接口有两个实现类:ArrayList类LinkedList类

// List接口的接口方法
void add(E e)			// 在末尾添加一个元素
void add(int index, E e)       // 在指定索引添加一个元素
int remove(int index)			// 删除指定索引的元素
int remove(Object e)		// 删除某个元素
E get(int index)			// 获取指定索引的元素
int size()			// 获取链表大小(包含元素的个数)

2、实现类区别

  • ArrayList类
    添加元素,但是数组已满,没有空闲位置的时候,ArrayList先创建一个更大的新数组,然后把旧数组的所有元素复制到新数组,紧接着用新数组取代旧数组

  • LinkedList类

    它的内部每个元素都指向下一个元素

ArrayList LinkedList
获取指定元素 速度很快 需要从头开始查找元素
添加元素到末尾 速度很快 速度很快
在指定位置添加/删除 需要移动元素 不需要移动元素
内存占用 较大

所以,优先使用ArrayList

3、遍历List

  • 使用list.size()进行for循环,只能应用于ArrayList,不能应用于LinkedList

  • 使用迭代器Iterator来访问ListIterator是由List的实例调用iterator()方法的时候创建的

Iterator对象有两个方法:boolean hasNext()判断是否有下一个元素,E next()返回下一个元素

import java.util.Iterator;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = List.of("apple", "pear", "banana");
        for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
            String s = it.next();
            System.out.println(s);
        }
    }
}

for each循环遍历集合

// for each循环本身就可以帮我们使用Iterator遍历

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = List.of("apple", "pear", "banana");
        for (String s : list) {
            System.out.println(s);
        }
    }
}

4、比较List中的元素是否相等

  • List中查找元素时,List的实现类通过元素的equals()方法比较两个元素是否相等,因此,放入的元素必须正确覆写equals()方法,Java标准库提供的StringInteger等已经覆写了equals()方法

  • 如果不调用Listcontains()indexOf()这些方法,那么放入的元素就不需要实现equals()方法。

元素对象重写equals()方法:

  1. 先确定实例“相等”的逻辑,即哪些字段相等,就认为实例相等;

  2. instanceof判断传入的待比较的Object是不是当前类型,如果是,继续比较,否则,返回false

  3. 对引用类型用Objects.equals(a, b)比较,对基本类型直接用==比较。

public boolean equals(Object o) {
    if (o instanceof Person) {
        Person p = (Person) o;
        boolean nameEquals = false;
        if (this.name == null && p.name == null) {
            nameEquals = true;
        }
        if (this.name != null) {
            nameEquals = this.name.equals(p.name);
        }
        return nameEquals && this.age == p.age;
    }
    return false;
}
// 重写equals()方法,简写版
public boolean equals(Object o) {
    if (o instanceof Person) {
        Person p = (Person) o;
        return Objects.equals(this.name, p.name) && this.age == p.age;
    }
    return false;
}

四、Set接口

放入Set的元素,要正确实现equals()hashCode()方法,否则该元素无法正确地放入Set

1、接口方法

boolean add(E e)		// 将元素添加进Set<E>
boolean remove(Object e)		// 将元素从Set<E>删除
boolean contains(Object e)   //	判断是否包含元素

2、实现类

  • HashSet是无序的,因为它实现了Set接口,并没有实现SortedSet接口
  • TreeSet是有序的,因为它实现了SortedSet接口

3、遍历

public class Main {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("apple");
        set.add("banana");
        set.add("pear");
        set.add("orange");
        for (String s : set) {
            System.out.println(s);
        }
    }
}

五、Map接口

Map也是一个接口,最常用的实现类是HashMap

Map是一种 键-值 映射表,当我们调用put(K key, V value)方法时,就把keyvalue做了映射并放入Map。当我们调用V get(K key)时,就可以通过key获取到对应的value。如果key不存在,则返回null

1、存键值对——put(key, value)

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Xiao Ming", 99);
        Map<String, Student> map = new HashMap<>();
        map.put("Xiao Ming", s); // 将"Xiao Ming"和Student实例映射并关联

    }
}

2、取数据——get(key)

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Xiao Ming", 99);
        Map<String, Student> map = new HashMap<>();
        map.put("Xiao Ming", s); // 将"Xiao Ming"和Student实例映射并关联
		Student target = map.get("Xiao Ming"); // 通过key查找并返回映射的Student实例

    }
}

3、其他方法

boolean containsKey(K key)    // 查询某个key是否存在
boolean	isEmpty()  // 判断是否为空
Set<K>	keySet()    //  获取map中所有key,一个Set集合
V	remove(Object key)   //  更具key删除数据
int	size()    // 获取 key-value的数量

4、遍历Map

(1)遍历 key来获取所有value

通过for each遍历keySet()

// 遍历 key来获取所有value
public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("apple", 123);
        map.put("pear", 456);
        map.put("banana", 789);
        for (String key : map.keySet()) {
            Integer value = map.get(key);
            System.out.println(key + " = " + value);
        }
    }

(2)同时遍历key和value

for each遍历entrySet(),直接获取key-value

public static void main(String[] args) {
    Map<String, Integer> map = new HashMap<>();
    map.put("apple", 123);
    map.put("pear", 456);
    map.put("banana", 789);
    // 利用entrySet()将映射关系存到Set中
    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        // 通过Entry对象的getKey,getValue获取 key和value
        String key = entry.getKey();
        Integer value = entry.getValue();
        System.out.println(key + " = " + value);
    }
}

5、获取value原理

  • 它内部通过空间换时间的方法,用一个大数组存储所有value,并根据key直接计算出value应该存储在哪个索引

  • 计算索引是调用key对象的hashCode()方法

6、注意点

key 是自定义类型的时候,必须重写hashCode()equals()

posted on   凉城旧巷  阅读(200)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示