Java容器体系

1、Java集合

在实现方法时,选择不同的数据结构会导致其实现风格以及性能存在着很大的差异。

  1. 需要快速的搜索成千上万个(甚至上百万个)有序的数据项吗?
  2. 需要快速的在有序的序列中间插入元素或删除元素吗?
  3. 需要建立键和值之间的关联吗?

总结一句话:根据不同需求选用不同的数据容器

因此要熟练掌握集合之间的关系,以及集合的特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHa9Wyx3-1580740152940)(images/01.png)]

2、将集合的接口与实现分离

![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-drYvGMaa-1580740152943)(images/03.png)]](https://img-blog.csdnimg.cn/20200203223131189.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pIT1VKSUFOX1RBTks=,size

==Java集合类库将接口(interface)与实现(implementation)==分离

接口:提供规范

实现类:进行底层实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GzL4TECO-1580740152948)(images/02.png)]

2.1、分析Queue体系

队列接口指出可以在队列的尾部添加元素,在队列的头部删除元素,并且可以查找队列中元素的个数。当需要收集对象,并按照"先进先出"的规则检索对象时就应该使用队列。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-quBucimG-1580740152949)(images/04.png)]

2.2、队列接口

队列接口的最简单形式

public interface Queue<E>{
   
    void add(E element);
    E remove();
    int size();
}

这个接口并没有说明队列是如何实现的。

队列通常有两种实现方式:

一种是使用循环数组

另一种是使用链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pKp9GXIJ-1580740152959)(images/05.png)]

2.3、队列实现

每一个实现都可以通过一个实现了Queue接口的类表示

public class CircularArrayQueue<E> implements Queue<E>{
    private int head;
    private int tail;
    public void add(E element){}
    public E remove(){.....}
    .....
}
public class LinkedListQueue<E> implements Queue<E>{
    private Link head;
    private Link tail;
    
    public void add(E element){....}
    public E remove(){....}
    
}

实际上再Java中没有上述的两个类

在实际使用中如果需要一个循环数组队列,就可以使用ArrayDeque类;

​ 如果需要一个链表队列,就直接使用LinkedList类,这个类实现了Queue接口

2.4、使用(多态)

当在程序中使用队列时,一旦构建了集合就需要知道究竟使用了哪种实现。

因此,只有在构建集合对象时,使用具体的类才有意义。可以使用接口类型存放集合的引用

Queue<Customer> expressLane = new CircularArrayQueue<>(100);//多态的使用
expressLane.add(new Customer("Harry"));

利用这种方式,一旦改变了想法,就可以轻松的使用另外一种不同的实现。只需要对程序中的一个地方做出修改、

expressLane = new LinkedListQueue<>();//多态的使用

在研究API文档时,会发现另外一组名字以abstract开头的类;

例如,AbstractQueue这些类是为类库实现者而设计的;方便对Queue接口的实现

3、Collection接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VHr3kl2e-1580740152960)(images/01.png)]

在Java类库中,集合类的基本接口是Collection接口

官方API

The root interface in the collection hierarchy. 集合层次结构中的根接口。

A collection represents a group of objects, known as its elements. 集合表示一组对象,称为其元素

Some collections allow duplicate elements and others do not. Some are ordered and others unordered.

一些集合允许重复的元素,而另外一些不允许。一些是有序的,而其他则是无序的。

The JDK does not provide any direct implementations of this interface: it provides implementations of more specific subinterfaces like Set and List.

JDK不提供此接口的任何直接实现:它提供更具体的子接口(例如SET)的是实现、

This interface is typically used to pass collections around and manipulate them where maximum generality is desired.

该接口通常用于传递集合并在需要最大通用性的地方操作他们。

Bags or multisets (unordered collections that may contain duplicate elements) should implement this interface directly.

Bags或者多集(可能包含重复元素的无序集合)应该直接实现此接口。

All general-purpose Collection implementation classes (which typically implement Collection indirectly through one of its subinterfaces) should provide two “standard” constructors: a void (no arguments) constructor, which creates an empty collection, and a constructor with a single argument of type Collection, which creates a new collection with the same elements as its argument.

所有通用Collection的实现类(通常为Collection的子接口的实现类)应该提供两个标准的构造器:一个无参数的构造器(创建一个空的集合);一个包含一个Collection类型的单个参数,并使用参数中的元素创建一个新的集合。

In effect, the latter constructor allows the user to copy any collection, producing an equivalent collection of the desired implementation type.

实际上,后一个构造函数允许用户复制任何集合,从而生成需要实现类型的等效集合。

There is no way to enforce this convention (as interfaces cannot contain constructors) but all of the general-purpose Collection implementations in the Java platform libraries comply.

没有强制执行此约定的方法(因为接口不能包含构造函数),但是Collection Java平台库中的所有实现都可以遵循。

Certain methods are specified to be optional. If a collection implementation doesn’t implement a particular operation, it should define the corresponding method to throw UnsupportedOperationException. Such methods are marked “optional operation” in method specifications of the collections interfaces.

某些方法被指定为 可选方法。如果集合实现未实现特定操作,则应定义相应的throw方法 UnsupportedOperationException。此类方法在集合接口的方法规范中标记为“可选操作”。

Some collection implementations have restrictions on the elements that they may contain.

一些集合实现对它们可能包含的元素有限制。

For example, some implementations prohibit null elements, and some have restrictions on the types of their elements.

例如,某些实现禁止使用null元素,而某些实现对其元素类型有限制。

Attempting to add an ineligible element throws an unchecked exception, typically NullPointerException or ClassCastException.

试图添加不合格的元素会抛出未经检查的异常,通常 NullPointerExceptionClassCastException

Attempting to query the presence of an ineligible element may throw an exception, or it may simply return false; some implementations will exhibit the former behavior and some will exhibit the latter.

尝试查询不合格元素的存在可能会引发异常,或者可能仅返回false;否则,可能会抛出异常。

More generally, attempting an operation on an ineligible element whose completion would not result in the insertion of an ineligible element into the collection may throw an exception or it may succeed, at the option of the implementation. Such exceptions are marked as “optional” in the specification for this interface.

更一般地,尝试对不合格元素执行操作,该操作的完成不会导致将不合格元素插入集合中,这可能会导致异常,也可能会成功,具体取决于实现。此类异常在此接口的规范中标记为“可选”。

It is up to each collection to determine its own synchronization policy.

由每个集合决定自己的同步策略。

In the absence of a stronger guarantee by the implementation, undefined behavior may result from the invocation of any method on a collection that is being mutated by another thread; this includes direct invocations, passing the collection to a method that might perform invocations, and using an existing iterator to examine the collection.

在实现没有更强有力的保证的情况下,未定义的行为可能是由于调用另一个线程正在变异的集合上的任何方法而导致的;这包括直接调用,将集合传递给可能执行调用的方法,以及使用现有的迭代器检查集合。

Many methods in Collections Framework interfaces are defined in terms of the equals method.

Collections Framework接口中的许多方法都是根据equals方法定义的。

For example, the specification for the contains(Object o) method says: “returns true if and only if this collection contains at least one element e such that (o==null ? e==null : o.equals(e)).”

例如,该contains(Object o) 方法的规范说:“ true仅当此集合包含至少一个e诸如此类的元素时,才返回 (o==null ? e==null : o.equals(e))

This specification should not be construed to imply that invoking Collection.contains with a non-null argument o will cause o.equals(e) to be invoked for any element e.

这个规范应该 被解释为暗示调用Collection.contains 具有非空参数o将导致o.equals(e)被调用的任何元素e

Implementations are free to implement optimizations whereby the equals invocation is avoided, for example, by first comparing the hash codes of the two elements.

实现可以自由实现优化,从而equals避免了调用,例如通过首先比较两个元素的哈希码来避免调用。

(The Object.hashCode() specification guarantees that two objects with unequal hash codes cannot be equal.)

Object.hashCode()规范保证了具有不相等哈希码的两个对象不能相等。)

More generally, implementations of the various Collections Framework interfaces are free to take advantage of the specified behavior of underlying Object methods wherever the implementor deems it appropriate.

更一般而言,各种Collections Framework接口的实现均可Object在实现者认为适当的地方自由利用基础方法的指定行为。

Some collection operations which perform recursive traversal of the collection may fail with an exception for self-referential instances where the collection directly or indirectly contains itself.

某些执行集合递归遍历的集合操作可能会失败,但自引用实例的例外情况是,集合直接或间接包含自身。

This includes the clone(), equals(), hashCode() and toString() methods. Implementations may optionally handle the self-referential scenario, however most current implementations do not do so.

这包括 clone()equals()hashCode()toString() 方法。实现可以有选择地处理自引用场景,但是大多数当前实现不这样做。

View Collections

Most collections manage storage for elements they contain.

大多数集合管理它们包含的元素的存储。

By contrast, view collections themselves do not store elements, but instead they rely on a backing collection to store the actual elements.

相比之下,视图集合本身并不存储元素,而是依靠后备集合来存储实际元素。

Operations that are not handled by the view collection itself are delegated to the backing collection.

视图集合本身未处理的操作将委派给后备集合。

Examples of view collections include the wrapper collections returned by methods such as Collections.checkedCollection, Collections.synchronizedCollection, and Collections.unmodifiableCollection.

视图集合的例子包括通过诸如返回的包装集合 Collections.checkedCollectionCollections.synchronizedCollectionCollections.unmodifiableCollection

Other examples of view collections include collections that provide a different representation of the same elements, for example, as provided by List.subList, NavigableSet.subSet, or Map.entrySet.

视图集合的其他实例包括提供相同的元件的不同表示,例如,如提供通过集合List.subListNavigableSet.subSetMap.entrySet

Any changes made to the backing collection are visible in the view collection.

对后备集合所做的任何更改都可以在视图集合中看到。

Correspondingly, any changes made to the view collection — if changes are permitted — are written through to the backing collection.

相应地,对视图集合所做的任何更改(如果允许更改)都将写入到支持集合中。

Although they technically aren’t collections, instances of Iterator and ListIterator can also allow modifications to be written through to the backing collection, and in some cases, modifications to the backing collection will be visible to the Iterator during iteration.

虽然他们在技术上不是收藏,实例 IteratorListIterator还可以允许修改传递给底层收集编写,并且在某些情况下,修改为后盾集合将迭代中的迭代器可见。

Unmodifiable Collections

Certain methods of this interface are considered “destructive” and are called “mutator” methods in that they modify the group of objects contained within the collection on which they operate.

此接口的某些方法被认为是“破坏性的”,并被称为“变异器”方法,因为它们修改了操作它们的集合中包含的对象组。

They can be specified to throw UnsupportedOperationException if this collection implementation does not support the operation.

UnsupportedOperationException如果此收集实现不支持该操作,则可以将它们指定为引发 。

Such methods should (but are not required to) throw an UnsupportedOperationException if the invocation would have no effect on the collection.

UnsupportedOperationException如果调用对集合没有影响,则此类方法应该(但不是必须)抛出

For example, consider a collection that does not support the add operation. What will happen if the addAll method is invoked on this collection, with an empty collection as the argument? The addition of zero elements has no effect, so it is permissible for this collection simply to do nothing and not to throw an exception.

例如,考虑一个不支持该add操作的集合。如果 addAll方法在此集合上调用,并以一个空集合作为参数?零元素的加法无效,因此允许此集合简单地不执行任何操作且不引发异常。

However, it is recommended that such cases throw an exception unconditionally, as throwing only in certain cases can lead to programming errors.

但是,建议此类情况无条件地引发异常,因为仅在某些情况下引发可能会导致编程错误。

An unmodifiable collection is a collection, all of whose mutator methods (as defined above) are specified to throw UnsupportedOperationException.

一个不可修改的集合是一个集合,其所有mutator方法(如上所定义)被指定为抛出 UnsupportedOperationException

Such a collection thus cannot be modified by calling any methods on it.

因此,无法通过在其上调用任何方法来修改此类集合。

For a collection to be properly unmodifiable, any view collections derived from it must also be unmodifiable.

为了使集合正确不可修改,从其派生的任何视图集合也必须不可修改。

For example, if a List is unmodifiable, the List returned by List.subList is also unmodifiable.

例如,如果一个列表不可修改,则返回的列表 List.subList也是不可修改的。

An unmodifiable collection is not necessarily immutable.

不可修改的集合不一定是不变的。

If the contained elements are mutable, the entire collection is clearly mutable, even though it might be unmodifiable.

如果所包含的元素是可变的,则整个集合显然是可变的,即使它可能不可修改。

For example, consider two unmodifiable lists containing mutable elements.

例如,考虑两个包含可变元素的不可修改列表。

The result of calling list1.equals(list2) might differ from one call to the next if the elements had been mutated, even though both lists are unmodifiable. However, if an unmodifiable collection contains all immutable elements, it can be considered effectively immutable.

list1.equals(list2)如果两个元素都是不可修改的,则调用的结果 可能会因一次调用而与另一次调用有所不同。但是,如果不可修改的集合包含所有不可变元素,则可以将其视为有效不可变。

Unmodifiable View Collections

An unmodifiable view collection is a collection that is unmodifiable and that is also a view onto a backing collection. Its mutator methods throw UnsupportedOperationException, as described above, while reading and querying methods are delegated to the backing collection. The effect is to provide read-only access to the backing collection. This is useful for a component to provide users with read access to an internal collection, while preventing them from modifying such collections unexpectedly. Examples of unmodifiable view collections are those returned by the Collections.unmodifiableCollection, Collections.unmodifiableList, and related methods.

Note that changes to the backing collection might still be possible, and if they occur, they are visible through the unmodifiable view. Thus, an unmodifiable view collection is not necessarily immutable. However, if the backing collection of an unmodifiable view is effectively immutable, or if the only reference to the backing collection is through an unmodifiable view, the view can be considered effectively immutable.

This interface is a member of the Java Collections Framework.

  • Implementation Requirements:

    The default method implementations (inherited or otherwise) do not apply any synchronization protocol. If a Collection implementation has a specific synchronization protocol, then it must override default implementations to apply that protocol.

Java集合中常用的接口

序号接口描述
1Collection接口 Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection 接口存储一组不唯一,无序的对象。
2List接口 List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。
3SetSet 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。
4SortedSet继承于Set保存有序的集合。
5Map Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
6Map.Entry 描述在一个Map中的一个元素(键/值对)。是一个Map的内部类。
7SortedMap继承于 Map,使 Key 保持在升序排列。
8Enumeration这是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。这个传统接口已被迭代器取代。

4、迭代器Iterator

公共接口Iterator

集合上的迭代器。 在Java Collections FrameworkIteratorEnumeration

  • 迭代器允许调用者在迭代期间使用定义明确的语义从基础集合中删除元素。
  • 方法名称已得到改进。

该接口是 Java Collections Framework的成员 。

public interface Iterator<E>{
    E next();
    boolean  hasNext();
    void remove();
    default void forEachRemaining(Consumer<? super E> action);
}

通过反复调用next方法,可以逐个访问集合中的每个元素。但是,如果达到了集合的末尾,next方法将会抛出一个NoSuchElementException。因此,需要在调用next之前调用hasNext方法。如果迭代器对象还有多个供访问的元素,则这个方法就返回true。如果要查看这个集合中的所有元素,就请求一个迭代器,并在hasNext返回true时反复的调用next方法

Collection<String> c=...;
Iterator<String> iter = c.iterator();
while(iter.hasNext()){
    String element = iter.next();
    do  Something  with element; 
}

for each循环可以更加简练的表示同样的循环操作

for(string element:c){
    do something with element
}

编译期简单的将for each循环翻译为带有迭代器的循环

Iterable接口

for each循环可以与任何实现了Iterable接口的对象一起工作;这个接口只包含一个抽象方法:

实现此接口可使对象成为增强型 for语句(有时称为“ for-each循环”语句)的目标。

public interface Iterable<E>{
    Iterator<E> iterator();
}

Collection接口可以扩展了Iterable接口;因此,对于标准类库中的任何集合都可以使用for each循环

元素被访问的顺序取决于集合类型。如果对ArrayList进行迭代,迭代器将从索引0开始,每迭代一次,索引值加1.然而,如果访问HashSet中的元素,每个元素将会按照某种随机的次序出现。虽然可以确定在迭代过程中能够遍历到集合中的所有元素,但无法预知元素被访问的次序。这对于计算总和或统计符合某个条件的元素个数这类与顺序无关的操作来说,并不是问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ufQ2heNN-1580740152985)(images/06.png)]

**Iterator接口的remove方法将会删除上次调用next方法时返回的元素。在大多数情况下,在决定删除某个元素之前应该先看一下这个元素是很具有实际意义的,然而,如果想要删除指定位置上的元素,仍然需要越过这个元素。**例如,下面是如何删除字符串集合中的第一个元素的方法:

Iterator<String> it = c.iterator<>();
it.next();//skip over the first elemet
it.remove(); //now remove it

5、泛型实用方法(JAVA已经实现)

由于CollectionIterator都是泛型接口,可以编写操作任何集合类型的实用反方、

例如,下面是一个检测任意集合是否包含指定元素的泛型方法:

public static<E> boolean contains(Collection<E> c,Object o){
    for(E element : c){
        if(element.equals(obj)){
            return true;
        }
        
    }
    return false;
}

Java类库的设计者认为:这些实用方法中的某些方法非常有用,应该将他们提供给用户使用。这样,类库的使用者就不必自己重新构建这些方法了。contains就是这样一个实用方法

事实上,Collection接口声明了很多有用的方法,所有实现类都必须提供这些方法,下面列举了其中的一部分:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QcJTdoC3-1580740152986)(images/07.png)]

如果实现Collection接口的每一个类都要提供如此多的例行方法将是一件很烦人的事情;为了能够让实现者能够跟容易的实现这个接口,Java类库提供了一个类AbstractionCollection,它将基础方法sizeiterator抽象化了。

公共抽象类AbstractCollection
扩展对象
实现Collection

此类提供Collection要实现不可修改的集合,程序员只需扩展此类并为iteratorsize方法提供实现。(iterator 方法返回的迭代器必须实现hasNextnext。)

要实现可修改的集合,程序员必须另外重写此类的add方法(否则将抛出 UnsupportedOperationException),并且该iterator方法返回的迭代器 必须另外实现其remove 方法。

根据接口规范中Collection的建议,程序员通常应提供一个void(无参数)和 构造函数 Collection

此类中每个非抽象方法的文档都详细描述了其实现。如果正在实现的集合允许更有效的实现,则可以覆盖这些方法中的每一个。

此类是 Java Collections Framework的成员 。

    
   /**
     * Returns an iterator over the elements contained in this collection.
     *
     * @return an iterator over the elements contained in this collection
     */
    public abstract Iterator<E> iterator();

    public abstract int size();


    /**
     * {@inheritDoc}
     *
     * <p>This implementation returns <tt>size() == 0</tt>.
     */
    public boolean isEmpty() {
        return size() == 0;
    }

    /**
     * {@inheritDoc}
     *
     * <p>This implementation iterates over the elements in the collection,
     * checking each element in turn for equality with the specified element.
     *
     * @throws ClassCastException   {@inheritDoc}
     * @throws NullPointerException {@inheritDoc}
     */
    public boolean contains(Object o) {
        Iterator<E> it = iterator();
        if (o==null) {
            while (it.hasNext())
                if (it.next()==null)
                    return true;
        } else {
            while (it.hasNext())
                if (o.equals(it.next()))
                    return true;
        }
        return false;
    }

6、Java集合框架中的接口

Java中容器总结的参考资料

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e1mSWRdg-1580740152988)(images/01.png)]

集合中有两个基本集合:CollectionMap

//Collection;
public interface Collection<E> extends Iterable<E> {}

//Map
public interface Map<K,V> {}

6.1、Collection

Collection接口是集合类根接口,Java中没有提供这个接口的直接的实现类。但是却让其被继承产生了两个接口,就是SetList

Set中不能包含重复的元素。

List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式

Collection下面分为三大类ListSet,Queue

6.1.1、List (有序、可重复 )

/**

公共接口List <E> 
扩展了Collection <E>
有序集合(也称为序列)。该界面的用户可以精确控制列表中每个元素的插入位置。用户可以通过其整数索引(列表中的位置)访问元素,并在列表中搜索元素。
与集合不同,列表通常允许重复的元素。更正式地讲,列表通常允许使用成对的元素e1,e2 例如和e1.equals(e2),并且如果它们完全允许使用空元素,则通常允许使用多个空元素。并非无法想象有人希望通过在用户尝试插入运行时异常时抛出运行时异常来实现禁止重复的列表,但是我们希望这种用法很少见。

该List接口放置额外的约定,超过指定Collection接口上的合同 iterator,add,remove,equals,和 hashCode方法。为了方便起见,此处还包含其他继承方法的声明。

该List接口提供了四种位置(索引)访问列表元素的方法。列表(如Java数组)从零开始。请注意,对于某些实现(LinkedList例如,类),这些操作可能会按与索引值成比例的时间执行。因此,如果调用者不知道实现,则遍历列表中的元素通常比对其进行索引更可取。

该List接口提供了一个称为的特殊迭代器,ListIterator除了Iterator接口提供的常规操作之外,该迭代器还 允许元素插入和替换以及双向访问 。提供一种获取列表迭代器的方法,该列表迭代器从列表中的指定位置开始。

该List接口提供了两种搜索指定对象的方法。从性能的角度来看,应谨慎使用这些方法。在许多实现中,它们将执行昂贵的线性搜索。

该List接口提供了两种方法,可以有效地在列表中的任意点插入和删除多个元素。

注意:尽管允许列表将自身包含为元素,但建议格外小心:equalsand hashCode 方法在这样的列表上不再有很好的定义。

一些列表实现对它们可能包含的元素有限制。例如,某些实现禁止使用null元素,而某些实现对其元素类型有限制。试图添加不合格的元素会抛出未经检查的异常,通常 NullPointerException或ClassCastException。尝试查询不合格元素的存在可能会引发异常,或者可能仅返回false;否则,可能会抛出异常。一些实现将表现出前一种行为,而某些将表现出后者。更一般地,尝试对不合格元素进行操作,该操作的完成不会导致将不合格元素插入列表中,这可能会导致异常或成功实现,具体取决于实现方式。此类异常在此接口的规范中标记为“可选”。

不可修改的清单
在List.of和 List.copyOf静态工厂方法提供了一种方便的方式来创建不可修改的列表。List 这些方法创建的实例具有以下特征:

它们是不可修改的。元素无法添加,删除或替换。调用List上的任何mutator方法总是会导致UnsupportedOperationException抛出该异常。但是,如果所包含的元素本身是可变的,则可能导致列表的内容似乎发生变化。
他们不允许使用null元素。尝试使用null元素创建它们会 导致NullPointerException。
如果所有元素都是可序列化的,则它们是可序列化的。
列表中元素的顺序与提供的参数或提供的数组中的元素的顺序相同。
它们是基于价值的。调用者不应对返回实例的身份做任何假设。工厂可以自由创建新实例或重用现有实例。因此,在这些实例上的身份敏感操作(引用相等(==),身份哈希码和同步)不可靠,应避免。
它们按照“ 序列化表格” 页面上的指定进行 序列化。
该接口是 Java Collections Framework的成员 。
**/

List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。

List是一个有序集合(ordered Collection)。

元素会增加到容器中的特定位置。

可以采用两种方式访问元素:使用迭代器访问使用一个整数索引来访问

后一种称为随机访问(Random access);因为这样可以按任意顺序访问元素;与之不桶,使用迭代器访问时,必须顺序的访问元素

List接口定义了很多歌用于随机访问的方法

void add(int index,E element)
    
void remove(int index)
    
 E get(int index)
    
 E set(int index,E element)

特点

有序;可以重复

底层实现有

LinkedList:底层链表;方便插入和删除,不方便遍历

ArrayList;底层数组;方便查询,遍历

public class LinkedList<E>  extends AbstractSequentialList<E>  implements List<E>, Deque<E>, Cloneable, java.io.Serializable//LinkedList;
    
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable//ArrayList


  • 类型参数:

    E -此列表中元素的类型

  • 所有超级接口:

    CollectionIterable

  • 所有已知的实施类:

    AbstractListAbstractSequentialListArrayListAttributeListCopyOnWriteArrayListLinkedListRoleListRoleUnresolvedListStackVector

6.1.2、Set( 无序、不能重复)

Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。

体系

  • 所有超级接口:

    CollectionIterable

  • 所有已知的子接口:

    EventSetNavigableSetSortedSet

  • 所有已知的实施类:

    AbstractSetConcurrentHashMap.KeySetViewConcurrentSkipListSetCopyOnWriteArraySetEnumSetHashSetJobStateReasonsLinkedHashSetTreeSet

6.1.3、Queue

先进先出

  • 类型参数:

    E -此队列中保留的元素类型

  • 所有超级接口:

    CollectionIterable

  • 所有已知的子接口:

    BlockingDequeBlockingQueueDequeTransferQueue

  • 所有已知的实施类:

    AbstractQueueArrayBlockingQueueArrayDequeConcurrentLinkedDequeConcurrentLinkedQueueDelayQueueLinkedBlockingDequeLinkedBlockingQueueLinkedListLinkedTransferQueuePriorityBlockingQueuePriorityQueueSynchronousQueue

6.2、Map

Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对map集合遍历时先得到键的set集合,对set集合进行遍历,得到相应的值。

/**
  将键映射到值的对象。映射不能包含重复的键;每个键最多可以映射到一个值。
	
**/


public interface Map<K,V> {
}

实现类:HashMapHashtableLinkedHashMapTreeMap

HashMap

HashMap是最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。因为键对象不可以重复,所以HashMap最多只允许一条记录的键为Null,允许多条记录的值为Null,是非同步的

Hashtable

Hashtable与HashMap类似,是HashMap的线程安全版,它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢,它继承自Dictionary类,不同的是它不允许记录的键或者值为null,同时效率较低。

ConcurrentHashMap

线程安全,并且锁分离。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。

LinkedHashMap

LinkedHashMap保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的,在遍历的时候会比HashMap慢,有HashMap的全部特性。

TreeMap

TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序(自然顺序),也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。不允许key值为空,非同步的;

6.3、主要实现类区别小结

Vector和ArrayList
1,vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。
2,如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%。如果在集合中使用数据量比较大的数据,用vector有一定的优势。
3,如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,如果频繁的访问数据,这个时候使用vector和arraylist都可以。而如果移动一个指定位置会导致后面的元素都发生移动,这个时候就应该考虑到使用linklist,因为它移动一个指定位置的数据时其它元素不移动。
ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以索引数据快,插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快。

arraylist和linkedlist
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。 这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

HashMap与TreeMap
1、 HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。
2、在Map 中插入、删除和定位元素,HashMap是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。
两个map中的元素一样,但顺序不一样,导致hashCode()不一样。
同样做测试:
在HashMap中,同样的值的map,顺序不同,equals时,false;
而在treeMap中,同样的值的map,顺序不同,equals时,true,说明,treeMap在equals()时是整理了顺序了的。

HashTable与HashMap
1、同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的。
2、HashMap允许存在一个为null的key,多个为null的value 。
3、hashtable的key和value都不允许为null。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值