Java集合框架是用于存储和操作数据的工具集合。它提供了实现不同数据结构的接口和类,这些数据结构包括列表、集合、队列和映射等。在这篇文章中,我们将详细介绍Java集合框架中的List、Set、Map等接口和实现类、迭代器和foreach语句、泛型、排序和查找算法等内容。
List接口和实现类
List接口是集合框架中最基本的接口之一。它表示一个有序的集合,包含一组要素,并且允许重复的元素。在Java中,List接口和它的实现类主要有以下几个:
- ArrayList
- LinkedList
- Vector
ArrayList
ArrayList是最常用的List实现类之一,它基于动态数组实现。通过add()方法向ArrayList中添加元素,通过get()方法获取元素值。
以下是示例代码:
ArrayList<String> list = new ArrayList<String>();
list.add("John");
list.add("Anna");
list.add("Peter");
System.out.println(list);
System.out.println(list.get(1));
输出结果如下:
[John, Anna, Peter]
Anna
LinkedList
LinkedList是一个基于链表实现的List集合类。使用它可以在任何位置添加或者删除元素,效率比ArrayList高。在LinkedList中,每个元素Node都有指向前一个元素Node和后一个元素Node的引用。
以下是示例代码:
LinkedList<String> list = new LinkedList<String>();
list.add("John");
list.add("Anna");
list.add("Peter");
System.out.println(list);
list.remove(1);
System.out.println(list);
输出结果如下:
[John, Anna, Peter]
[John, Peter]
Vector
Vector是一个和ArrayList相似的动态数组的实现类。它和ArrayList的区别在于,它是线程安全的,因此它效率比ArrayList低。
以下是示例代码:
Vector<String> vector = new Vector<String>();
vector.add("John");
vector.add("Anna");
vector.add("Peter");
System.out.println(vector);
System.out.println(vector.get(1));
输出结果如下:
[John, Anna, Peter]
Anna
Set接口和实现类
Set接口表示一个不包含重复元素的集合。它具有add()、remove()和contains()等方法。在Java中,Set接口和它的实现类主要有以下几个:
- HashSet
- LinkedHashSet
- TreeSet
HashSet
HashSet是最常用的Set实现类之一。它通过哈希表实现,可以达到O(1)的查询和访问时间。因此,它的查询速度比ArrayList、Vector、LinkedList等List实现类更快,但HashSet不保证所添加的元素的顺序。
以下是示例代码:
HashSet<String> set = new HashSet<String>();
set.add("John");
set.add("Anna");
set.add("Peter");
System.out.println(set);
set.remove("Anna");
System.out.println(set.contains("Anna"));
System.out.println(set);
输出结果如下:
[Anna, Peter, John]
false
[Peter, John]
LinkedHashSet
LinkedHashSet是一个具有可预测迭代顺序的HashSet。它具有在集合中插入元素的同时,维护着元素的迭代顺序。使用LinkedHashSet时,元素将按照插入的顺序迭代。
以下是示例代码:
LinkedHashSet<String> set = new LinkedHashSet<String>();
set.add("John");
set.add("Anna");
set.add("Peter");
System.out.println(set);
set.remove("Anna");
System.out.println(set.contains("Anna"));
System.out.println(set);
输出结果如下:
[John, Anna, Peter]
false
[John, Peter]
TreeSet
TreeSet是按排序顺序维护元素的一个集合。它是一个基于红黑树实现的Set集合类,可以保证添加的元素是有序的。使用TreeSet集合时,元素应该实现Comparable接口并重写compareTo方法。
以下是示例代码:
TreeSet<String> set = new TreeSet<String>();
set.add("John");
set.add("Anna");
set.add("Peter");
System.out.println(set);
set.remove("Anna");
System.out.println(set.contains("Anna"));
System.out.println(set);
输出结果如下:
[Anna, John, Peter]
false
[John, Peter]
Map接口和实现类
Map接口表示一个键值对映射的集合。它可以通过key来访问和获取对应的value。在Java中,Map接口和它的实现类主要有以下几个:
- HashMap
- LinkedHashMap
- TreeMap
HashMap
HashMap是一种快速的、无序的、键值对映射集合类。它通过哈希表实现,可以达到O(1)的查询和访问时间,因此,它的查询速度比List实现类更快。
以下是示例代码:
HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(101, "John");
map.put(102, "Anna");
map.put(103, "Peter");
System.out.println(map);
System.out.println(map.get(102));
输出结果如下:
{101=John, 102=Anna, 103=Peter}
Anna
LinkedHashMap
LinkedHashMap是一种按插入顺序排序的HashMap。它在遍历时可以按照元素添加的顺序输出,这个特性和LinkedList类似。
以下是示例代码:
LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
map.put(101, "John");
map.put(102, "Anna");
map.put(103, "Peter");
System.out.println(map);
System.out.println(map.get(102));
输出结果如下:
{101=John, 102=Anna, 103=Peter}
Anna
TreeMap
TreeMap是一种有序的、键值对映射集合类。它通过红黑树实现,键值对可以按顺序存储。使用TreeMap时,键值对的键应该实现Comparable接口并重写compareTo方法。
以下是示例代码:
TreeMap<Integer, String> map = new TreeMap<Integer, String>();
map.put(101, "John");
map.put(102, "Anna");
map.put(103, "Peter");
System.out.println(map);
System.out.println(map.get(102));
输出结果如下:
{101=John, 102=Anna, 103=Peter}
Anna
迭代器和foreach语句
迭代器是集合框架中的一种对象,它可以遍历所有的集合元素。通过实现Iterator接口,我们可以实现自己的迭代器类,并使用它来遍历集合元素。
以下是示例代码:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer value = iterator.next();
System.out.println(value);
}
输出结果如下:
1
2
3
foreach语句是Java SE5引入的一种新语言特性,可以更方便地遍历集合元素。它通过隐式调用迭代器实现。
以下是示例代码:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for (Integer value : list) {
System.out.println(value);
}
输出结果如下:
1
2
3
泛型
Java泛型是Java SE5中引入的一种新特性。泛型可以让我们编写更加安全和简洁的代码,同时提高程序的可读性和维护性。通过使用泛型,我们可以指定类、接口、方法的类型形参,分离类型的使用和类型的定义。
以下是示例代码:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for(Integer value : list) {
System.out.println(value);
}
输出结果如下:
1
2
3
在上述代码中,ArrayList
中的元素类型被限定为Integer
,可以保证在编译时和运行时都不会出现类型不一致的情况。而且这种限制可以提供更好的编译时类型检查,避免一些运行时出现的错误。
排序和查找算法
集合框架中的List集合通常有很多元素,对于它们的排序和查找,我们可以使用Java中提供的排序和查找算法。Java提供了多种排序算法,如快速排序、选择排序、堆排序,以及查找算法,如二分查找。
排序算法示例代码
使用Java提供的排序算法来对List集合元素进行排序,只需要调用Collections
类的sort()
方法即可。
以下是示例代码:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(4);
list.add(2);
list.add(5);
list.add(1);
Collections.sort(list);
System.out.println(list);
输出结果如下:
[1, 2, 4, 5]
以上代码调用了Collections
类的sort()
方法来对List集合元素进行排序,排序后的结果为升序排列。
查找算法示例代码
使用Java提供的查找算法可以快速地找到集合中元素的位置。
以下是示例代码:
ArrayList<String> list = new ArrayList<String>();
list.add("John");
list.add("Anna");
list.add("Peter");
int index = Collections.binarySearch(list, "Anna");
System.out.println(index);
输出结果如下:
1
以上代码调用了Collections
类的binarySearch()
方法来查找list
集合中字符串"Anna"的位置,返回值表示元素在集合中的索引。
补充:
动态数组
动态数组是一种可以调整大小的数组。通过使用动态数组,我们可以更加灵活地处理不确定的数据量。
动态数组的实现用到了内存动态分配和释放技术。每当动态数组的大小需要发生变化时,程序会重新分配一段连续的内存空间,并将原来的数据复制到新的空间中。
链表
链表是一种通过链式存储方式来实现的数据结构。链表中的每个节点包含了一个元素和它的下一个节点的地址。与动态数组不同,链表在插入和删除元素时具有更好的性能优势。
链表的实现可以使用单向链表、双向链表或者循环链表等方式。不同类型的链表各自具有不同的特点和优势。
哈希表
哈希表是一种基于哈希算法来实现的数据结构。它在内部使用哈希函数将关键字映射到表中的索引位置。当两个不同的关键字被映射到了相同的位置时,就产生了哈希碰撞,常用的解决办法是使用链式法或开放地址法。
哈希表具有较快的查找、插入和删除等操作速度,而且能够根据需要扩展。
红黑树
红黑树是一种自平衡的二叉查找树,它具有较好的查找和插入操作性能。红黑树的节点颜色可以是红色或黑色,并且满足以下五个性质:
- 根节点是黑色的;
- 每个叶节点(NIL节点,空节点)是黑色的;
- 每个红色节点的两个子节点都是黑色的;
- 从任一节点到其每个叶节点的所有路径都包含相同数目的黑色节点;
- 每个新插入的节点都是红色的。