List集合
List 集合是一个有序的集合,它可以存储和访问顺序排列的元素。List 集合有两种常用的实现类:ArrayList 和 LinkedList。
使用 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从入门到精通》
仅用于学习交流