0%

Java——容器1

常用的容器

  • Set: HashSet,LinkedHashSet,TreeSet,EnumSet(后三个有序)

  • List: ArrayList,LinkedList,Stack,Vector(全部有序)

  • Queue:LinkedBlockingQueue,ArraysBlockingQueue(全部有序)

  • Map: HashMap,TreeMap,LinkedHashMap,EnumMap,ConcurrentHashMap,IdentityHashMap(前三有序)

  • 容器的继承关系

Snipaste_2020-08-20_16-02-44

Iterable接口

  • Iterable是一个超级接口,被Collection所继承。它只有一个方法: Iterator iterator() //即返回一个迭代器
  • 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

  • Java中的Iterator功能比较简单,并且只能单向移动
    (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
      (2) 使用next()获得序列中的下一个元素。
      (3) 使用hasNext()检查序列中是否还有元素。
      (4) 使用remove()将迭代器新返回的元素删除。

  • 下面有一个小例子:

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
//实现Iterable接口
public class IterableClass implements Iterable<String> {
protected String[] words = {"A", "B", "C", "D", "E"};
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
private int index;
@Override
public boolean hasNext() {
return index<words.length;
}

@Override
public String next() {
return words[index++];
}
};
}

public static void main(String[] args) {
for (String s : new IterableClass()) {
System.out.print(s+" ");
}
}
}

Collection接口

  • 一个独立的元素序列,JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现。也就是一般不会直接使用Collection,而是会使用它的子类,如List或Set。
  • Collection会针对不同的子类规定不同的规则。比如:List必须按插入顺序保存元素;Set不能有重复的元素等等。

Map接口

  • Map是与Collection同层次的接口,它可以用来规定子类储存一组成对的“键值对”对象,允许使用键来查找值,也可以将它当成映射表或字典。

List接口

  • L。list是有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
  • 用户插入的顺序或者指定的位置就是元素插入的位置。它与Set不同,List允许插入重复的值

两个实现List接口的基本类型

  1. ArrayList:它长于随机访问元素,但是在List的中间插入与移除元素时较慢
  2. LinkedList:它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序访问。LinkedList在随机访问方面相对比较慢。

迭代器

  • 对于List,add()时插入元素的方法之一,而get()是取出元素的方法之一。但要使用容器,就必须对容器的确切类型进行编程,这会使代码不具备复用性。原本是对着List编码的,后面发现如果能够把相同的代码应用在Set,将会很方便,而迭代器就是来解决这个问题的。
  • 迭代器是一种设计模式,它的工作是遍历并选择序列中的对象,程序员不必知道改序列的底层结构。此外,迭代器通常被称为轻量级对象,即创建它的代价小
  • Java的Iterator只能单向移动,使用迭代器的步骤如下:
    1. 使用集合的iterator()方法可以返回一个Iterator对象。
    2. 使用Iterator对象的next()获取序列中的下一个元素
    3. 使用Iterator对象的hasNext()检查序列中是否还有元素
    4. 使用Iterator对象的remove()将迭代器新近返回的元素删除
  • 下面有一个小例子:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.muchlab.container;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

class Pet{
private String name;

public Pet(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
public class SimpleIteration {
public static void main(String[] args) {
//在这里需要注意的是:Arrays.asList()不可添加或删除元素,因为这个方法返回的是Arrays中继承AbstractList的内部类ArrayList,这个类并没有实现添加和删除操作。
ArrayList<Pet> pets = new ArrayList<>();
Collections.addAll(pets, new Pet("A"), new Pet("B"), new Pet("C"), new Pet("D"));
Iterator<Pet> iterator = pets.iterator();
while (iterator.hasNext()){
Pet p = iterator.next();
System.out.print("Pet:"+p.getName()+" ");
}
System.out.println();
for (Pet pet : pets) {
System.out.print("Pet:"+pet.getName()+" ");
}
iterator = pets.iterator();
for (int i = 0; i < 3; i++) {
iterator.next();
iterator.remove();
}
System.out.println();
for (Pet pet : pets) {
System.out.print("Pet:"+pet.getName()+" ");
}
}
}

LinkedList

  • LinkedList相比起ArrayList还添加了可以使用作栈Stack、队列Queue或双端队列的方法。
  • 获取元素:getFirst()、element()完全一样,都是返回列表的第一个元素,而不移除它,若List为空,则会抛出异常NoSuchElementException,peek()也是获取元素的方法,但它和前面两个方法的区别是它在List为空时会返回null。
  • 添加元素:addFirst()、add()、addLast()都相同,它们都将某个元素插入到列表的末尾。
  • 删除元素:removeFirst()和remove()完全一样,它们移除并返回列表的头,而removeLast()移除并返回列表的最后一个元素,但列表为空时,它们都会抛出异常NoSuchElementException。poll()则在列表为空时返回null。

Set接口

  • Set不保存重复的元素,最常被使用的是测试归属性,你可以很容易地询问某个对象是否在某个Set中,正因如此,查找是Set最重要地操作。通常的做法是选择一个HashSet的实现,专门对查找进行优化。

Set三种常用的实现类型

  1. HashSet:出于速度原因的考虑,HashSet使用的是散列函数,所以输出的顺序没有任何规律。
  2. TreeSet:TreeSet则将元素存储在红黑树数据结构中。
  3. LinkedHashSet:LinkedHashSet对元素的存储是跟HashSet一样,但它跟LinkedList一样使用链表来维护插入和删除操作。

总结

  1. Collection保存单一类型的元素,而Map保存相关联的键值对,这两者都不能持有基本类型,但是Java的自动包装机制对仔细地执行基本类型和其对应的包装类之间的双向转换。
  2. List可以建立数字索引和对象的关联,能够自动扩充容量
  3. 如果需要大量的随机访问,就使用ArrayList,如果需要使用大量的插入或删除元素,则使用LinkedList
  4. 各种Queue和栈的行y为,由LinkedList提供支持
  5. Map是一种将对象与对象相关联的设计。HashMap设计用来快速访问;TreeMap保存键始终处于排序状态,所以没有HashMap快;LinkedHashMap保持元素插入的顺序,但是也通过散列提供了快速访问的能力。
  6. Set不接受重复元素。HashSet提供最快的查询速度;而TreeSet保持元素处于排序状态;LinkedHashSet以插入顺序保存元素
  7. 建议不应该使用过时的Vector、Hashtable和Stack。
-------------本文结束感谢您的阅读-------------