Java学习笔记:List集合、Set集合与Map集合

List集合

List 集合是一个有序的集合,它可以存储和访问顺序排列的元素。List 集合有两种常用的实现类:ArrayListLinkedList

使用 List 集合时通常声明 List 类型,可通过不通过的实现类来实例化集合。通过 ArrayList 类、LinkedList 类分别实例化 List 集合的代码如下:

List<Example> list1 = new ArrayList<>();
List<Example> list2 = new LinkedList<>();

上述代码中 Example 可以是任何合法的 Java 数据类型,例如 integer、String 等基础数据类型,或者是已定义的类。

ArrayList 是一个动态数组,它可以根据需要增长或缩小。它适合随机访问元素,时间复杂度是O(1)。但是使用 ArrayList 在添加或删除元素时可能需要扩容或缩容,这会影响性能,故其插入或删除元素的效率较低。

LinkedList 是一个双向链表,其在添加或删除元素时只需要修改指针,不需要移动其他元素,且它可以在任何位置快速插入或删除元素。它适合顺序访问元素,但是随机访问效率较低,时间复杂度是O(n/2)。

所以,在选择 ArrayList 和 LinkedList 时要根据具体的需求和场景来决定。一般来说,如果需要频繁地访问元素而不需要经常地添加或删除元素,那么 ArrayList 可能更合适;如果需要频繁地添加或删除元素而不需要经常地访问元素,那么 LinkedList 可能更合适。

下面是两个例子,分别用 ArrayList 和 LinkedList 来存储一些数字,并进行一些操作:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ListExamples {
    public static void main(String[] args) {
        // 创建一个ArrayList对象
        List<Integer> arrayList = new ArrayList<>();
        // 添加一些元素
        arrayList.add(10);
        arrayList.add(20);
        arrayList.add(30);
        // 打印出arrayList
        System.out.println("arrayList: " + arrayList);
        // 访问第二个元素
        System.out.println("arrayList.get(1): " + arrayList.get(1));
        // 修改第三个元素
        arrayList.set(2, 40);
        // 打印出修改后的arrayList
        System.out.println("arrayList after set: " + arrayList);
        
        // 创建一个LinkedList对象
        List<Integer> linkedList = new LinkedList<>();
        // 添加一些元素
        linkedList.add(50);
        linkedList.add(60);
        linkedList.add(70);
        
         // 打印出linkedList
         System.out.println("linkedList: " + linkedList);
         // 访问第二个元素(效率低)
         System.out.println("linkedList.get(1): " + linkedList.get(1));
         // 删除第一个元素(效率高)
         linkedList.remove(0);
         // 打印出删除后的linkedList
         System.out.println("linkedList after remove: " + linkedList);       
    }
}

上述代码输出结果如下:

arrayList: [10, 20, 30]
arrayList.get(1): 20
arrayList after set: [10, 20, 40]
linkedList: [50, 60, 70]
linkedList.get(1): 60
linkedList after remove: [60, 70]

 

Set集合

Set 集合是一种不允许重复元素的容器,它继承了 Collection 接口,但是没有定义自己的方法。Set 集合有两个主要的实现类,一个是 HashSet,一个是 TreeSet

HashSet 是基于哈希表(实际上是一个 HashMap 实例)的,它的元素是无序的,此类允许使用 null 元素,其添加和查询都很快。比如,我们创建一个 HashSet,然后添加一些字符串元素,如下:

HashSet<String> hset = new HashSet<String>();
hset.add("geeks");
hset.add("for");
hset.add("practice");
hset.add("contribute");
hset.add("geeks");

注意,我们添加了两个相同的元素"geeks",但是 HashSet 不会存储重复的元素,所以只会有一个"geeks"在集合中。当我们打印这个集合时,我们会看到如下的输出:

HashSet contains:
contribute
practice
for
geeks

可以看到,输出的顺序和添加的顺序不一致,HashSet 不保证该顺序恒久不变,这是因为其是基于哈希表的,它根据元素的哈希值来存储和查找。

TreeSet 是基于红黑树的,它的元素是有序的,其添加和查询都比较慢。比如,我们创建一个 TreeSet,然后添加一些整数元素,如下:

TreeSet<Integer> tset = new TreeSet<Integer>();
tset.add(10);
tset.add(5);
tset.add(15);
tset.add(20);
tset.add(10);

注意,我们也添加了两个相同的元素10,但是 TreeSet 也不会存储重复的元素,所以只会有一个10在集合中。当我们打印这个集合时,我们会看到如下的输出:

TreeSet contains:
5
10
15
20

可以看到,输出的顺序和自然顺序一致,这是因为该类实现了 java.util.SortedSet 接口,其实现的 Set 集合在遍历集合时按照自然顺序递增排序,也可以按照指定比较器递增排序,它根据元素的大小来存储和查找。

Map集合

Map 集合包括 Map 接口以及 Map 接口的所有实现类。其没有继承 Collection 接口,它是一种键值对(key-value)的容器,其提供的是 key 到 value 的映射。它继承了 Collection 接口的子接口 Map。Map 集合中的每一个元素都包含一个键对象和一个值对象,键(key)对象不允许重复,每个 key 只能映射一个 value,但值对象可以重复。Map 集合可以根据键对象来快速查找或者删除对应的值对象。

Map 接口有两个主要的实现类,一个是 HashMap 类,一个是 TreeMap 类。

HashMap 类是基于哈希表的,它的键对象和值对象都可以为 null,但必须保证键的唯一性。该类通过哈希表实现,对内部的映射关系查询和添加元素都很快。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。比如,我们创建一个 HashMap,然后添加一些键值对,如下:

HashMap<Integer, String> hmap = new HashMap<Integer, String>();
hmap.put(1, "one");
hmap.put(2, "two");
hmap.put(3, "three");
hmap.put(4, "four");
hmap.put(null, null);

注意,我们添加了一个 null 键和一个 null 值,但是 HashMap 只允许存储一个 null 键和多个 null 值。当我们打印这个集合时,我们会看到如下的输出:

HashMap contains:
{null=null, 1=one, 2=two, 3=three, 4=four}

可以看到,输出的顺序和添加的顺序不一致,这是因为 HashMap 是基于哈希表的,它根据键对象的哈希值来存储和查找。

TreeMap 类是基于红黑树的,它的键对象必须实现 Comparable 接口或者指定一个比较器,它的元素是按照键对象的大小来排序的,但是添加和查询都比较慢。比如,我们创建一个 TreeMap,然后添加一些键值对,如下:

TreeMap<Integer, String> tmap = new TreeMap<Integer, String>();
tmap.put(1, "one");
tmap.put(2, "two");
tmap.put(3, "three");
tmap.put(4, "four");
tmap.put(5, null);

注意,我们添加了一个 null 值,但是 TreeMap 不允许存储 null 键,只允许存储多个 null 值。当我们打印这个集合时,我们会看到如下的输出:

TreeMap contains:
{1=one, 2=two, 3=three, 4=four, 5=null}

可以看到,输出的顺序和键对象的大小一致,这是因为 TreeMap 是基于红黑树的,该类实现的 Map 集合中的映射关系是根据键对象按照一定的顺序排列的,因此不允许键对象是 null。

注:建议使用 HashMap 类实现 Map 集合,因为由 HashMap 类实现的 Map 集合添加和删除映射关系效率更高。可以通过 HashMap 类创建 Map 集合,当需要顺序输出时,再创建一个完成相同映射关系的 TreeMap 实例。

本文部分内容参考了Sydney,一位AI助手,部分摘抄自 明日科技《Java从入门到精通》

仅用于学习交流

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值