Java集合
在集合类库中,接口与实现是分离的。以队列为例:队列接口Queue声明了所需的方法,而队列实现有循环数组和链表两种实现方式。可以使用接口类型存放集合的引用,利用这种方式,一旦改变了想法, 可以轻松地使用另外一种不同的实现。
一,集合框架中的接口
集合框架有两个基本接口:Collection(也称为集合,容易和集合框架混淆,注意甄别)和 Map。
在Collection可以通过boolean add(E element) 添加元素,在Map中由于映射包含键 / 值对,所以要用 put 方法来插人:V put(K key, V value)
要从集合读取元素,Collection可以用迭代器访问元素。不过,从映射中读取值则要使用 get 方法: V get(K key)
1,Collection接口
boolean add(E element);
Iterator<E> iterator();
迭代器
Iterator接口包含四个方法:
public interface Iterator<E>{
E next();
boolean hasNext();
void remove();
default void forEachRemaining(Consumer<? super E> action);
}
“ for each” 循环可以与任何实现了 Iterable 接口的对象一起工作, 这个接口只包含一个抽象方法
public interface Iterable<E>{
Iterator<E> iterator();
}
Collection 接口扩展了 Iterable 接口。因此, 对于标准类库中的任何集合都可以使用“ for each” 循环。在 Java SE 8中,甚至不用写循环。可以调用 forEachRemaining 方法并提供一个lambda 表达式(它会处理一个元素)。将对迭代器的每一个元素调用这个 lambda 表达式,直到再没有元素为止。
iterator.forEachRemaining(element -> do something with element);
Collection接口全部方法
Iterator<E> iterator();
int size();
boolean isEmpty();
boolean contains(Object obj);
boolean containsAll(Collection<?> other);
boolean add(Object element);
boolean addAll(Collection<? extends E> other);
boolean remove(Object obj);
boolean removeAll(Collection<?> other);
default boolean removeIf(Predicate<? super E> filter);
boolean retainAll(Collection<?> c);
void clear();
Object[] toArray();
<T> T[] toArray(T[] a);
List接口
扩展于Collection接口
List 是一个有序集合,元素会增加到容器中的特定位置。可以采用两种方式访问元素:使用迭代器访问,或者使用一个整数索引来访问(随机访问)。
List 接口定义了多个用于随机访问的方法:
void add(int index, E element) ;
E remove(int index) ;
E get(int index) ;
E set(int index, E element);
Set接口(集)
扩展于Collection接口
Set 接口等同于 Collection 接口,不过其方法的行为有更严谨的定义。
- 集(set) 的 add方 法不允许增加重复的元素。
- 要适当地定义集的 equals 方法:只要两个集包含同样的元素就认为是相等的,而不要求这些元素有同样的顺序。
- hashCode 方法的定义要保证包含相同元素的两个集会得到相同的散列码。
二,集合框架中的实现(具体的集合)
在表 9-1 中, 除了以 Map 结尾的类之外, 其他类都实现了Collection接口,而以Map结尾的类实现了Map接口。
1,链表LinkList
- 链表是一个有序集合
- 在 Java 程序设计语言中,所有链表实际上都是双向链接的
void add(E element) 方法不返回boolean类型的值,假定添加操作总会改变链表
void add(int index, E element) ;
E remove(int index) ;
E get(int index) ;
E set(int index, E element);
void addAll (int i, Collection<? extends E> elements );
int indexOf(Object element);
int lastlndexOf(Object element)
LinkedList()
LinkedList(Collection<? extends E> elements)
void addFirst(E element)
void addLast(E element)
E getFirst()
E getLast()
E removeFirst()
E removeLast()
2,数组列表ArrayList
方法基本与List接口方法名相同。
3,散列表
散列表为每个对象计算一个整数,称为散列码(hash code) 。散列码是由对象的实例域产生的一个整数。更准确地说, 具有不同数据域的对象将产生不同的散列码。
注意,自己实现的hashCode方法应该与 equals方法兼容,即如果 a.equals(b)为true, a与 b必须具有相同的散列码。
图中链表数组,每个列表称为桶。
基于散列表查找是否相同的元素:首先计算hashcode得到散列码,与桶总数求余,得到索引,最后使用新对象与桶中所有对象进行比较,查看对象是否存在。大大缩短比较时间。
利用散列表思想:HashSet(散列集)来判断集中相同元素是否存在
4,树集TreeSet
树集是一个有序集合,对集合进行遍历时,每个值将自动按照排序后的顺序呈现。排序是用树结构完成的(红黑树),每次将一个元素添加到树中时,都会被放置在正确的排序位置上。
5,队列与双端队列
暂略
三,映射
映射用来存放键 / 值对。如果提供了键,就能够查找到值。Java类库为映射提供了两个通用的实现:HashMap和TreeMap。这两个类都实现了Map接口。
- HashMap对键进行散列, TreeMap用键的整体顺序对元素进行排序, 并将其组织成搜索树。散列或比较函数只能作用于键。与键关联的值不能进行散列或比较。
1,常用方法
V get(Object key)
default V getOrDefault(Object key, V defaultValue)
V put(K key, V value)
void putAll(Map<? extends K , ? extends V> entries)
boolean containsKey(Object key)
boolean containsValue(Object value)
default void forEach(BiConsumer<? super K ,? super V> action)
2,映射视图
有3种视图:键集、值集合(不是一个集)以及键/值对集。
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
Map.Entry<K,V>类中的方法:
K getKey()
V getValueC)
V setVa1ue(V newValue)
|