Java中的集合
在JavaScript中,常用的集合有Array、Set和Map,那在Java中,常用的集合有哪些?其实,大体分为四类,分别是Array、Set、队列和Map。
列表
一般来说,Java中有数组、ArrayList
类和LinkedList
类三种列表类型。我们知道数组有一个大问题,它是固定的长度的,不适合动态增长或缩减,所以,一般很少使用。ArrayList支持动态分配长度,但有一个缺点是从中删除或插入一个元素的开销很大。因为其位于被删除元素之后的所有元素都要向数组的前端移动,插入时也是如此。而LinkedList因为是链表
结构,所以,它可以在任意位置高效删除或添加,但是,其随机访问并不高效。
综上,如果需要对列表中进行随机访问,就使用数组或者ArrayList,而不要使用LinkedList;如果需要经常在列表中进行删除或插入操作,建议使用LinkedList。
最后,来看一个小例子:
var a = new LinkedList<String>();
a.add("AA");
a.add("BB");
a.add("CC");
如上,创建了一个LinkedList,并且在其中添加了三个元素。
Set
Set集合,常有的HashSet
类和TreeSet
类,对于Set来说,其没有重复的值:
var words = new HashSet<String>();
words.add("aa");
words.add("bb");
words.add("aa");
最终,words的的长度为2,因为最后一个aa和第一个aa是重复的,也就是说,HashSet类会自动进行去重。
TreeSet与HashSet十分相似,从某种情况看,TreeSet是对HashSet的一种改进,HashSet是无序的,TreeSet是有序
的,这意味着在TreeSet中的值会按照某种顺序自行排序:
var books= new TreeSet<String>();
books.add("bb");
books.add("aa");
books.add("aa");
如上,最终books中的值为[aa, bb]
,虽然我们第一个插入的值为“bb”,但是,TreeSet在内部自动做了排序处理。当然,也做了去重操作。
综上,TreeSet比HashSet功能更加强大,当然,随之而言,其性能也会稍微低一些。
队列
队列允许你高效地在尾部添加元素,并在头部删除元素。双端队列
(deque)允许在头部和尾部都能高效地添加或删除元素。
除此之外,还有一个强大的优先队列
(priority queue),其中的元素可以按照任意顺序插入,但会按照有序的顺利进行检索。所以,这种类型特别适合用于任务调度
,每一个任务有一个优先级,任务以随机顺序添加到队列中,其添加(add)和删除(remove)操作可以让最小的元素自动移动到根。来看一个例子:
var pq = new PriorityQueue<LocalDate>();
pq.add(LocalDate.of(1906, 12, 9));
pq.add(LocalDate.of(1815, 12, 10));
pq.add(LocalDate.of(1903, 12, 3));
pq.add(LocalDate.of(1910, 6, 22));
System.out.println("Iterating over elements...");
for (LocalDate date: pq) {
System.out.println(date);
}
System.out.println("Removing elements ...");
while (!pq.isEmpty()) {
System.out.println(pq.remove());
}
结果为:
Iterating over elements...
1815-12-10
1906-12-09
1903-12-03
1910-06-22
Removing elements ...
1815-12-10
1903-12-03
1906-12-09
1910-06-22
发现了吗?这里的迭代顺序并不是有序的,但是,删除操作却总是删除剩余元素中最小的那个元素。
Map
Map被称为映射,说白了,就是存键值对
的集合,一个键对应一个值,这样,只要拥有了键,可以方便快速地获得相应的值。
Java类库为Map提供了两个通用的实现,HashMap和TreeMap,这两个类都实现了Map接口。HashMap对键进行散列,TreeMap则根据键的顺序
将元素组织为一个搜索树。来看一个简单例子:
var staff = new HashMap<Integer, String>();
staff.put(200, "Foo");
staff.put(150, "Bar");
staff.put(300, "Ca");
System.out.println(staff);
staff.remove(150);
staff.put(300, "Harry");
System.out.println(staff.get(200));
结果为:
{150=Bar, 200=Foo, 300=Ca}
Foo
上面代码中定义了一个简单的HashMap,和Set不同的是,添加元素,Map使用的是put方法。
小结
在实际的开发中,选择合适的数据集合非常重要,尤其是当数据集比较大(上百万)时,就必须仔细考虑性能的问题,所以,弄清楚每种集合的优缺点有助于我们作出正确选择。