目录

单例集合(Collection)

1:List接口

1-1:ArrayList

1-2:LinkedList

1-3:Vector

2:Set接口

2-1:HashSet

2-2:TreeSet

2-3:LinkedHashSet

双列集合(Map)

1-1:HashMap

1-2:TreeMap

1-4:HashTable


集合详细图

Java代码的map的value值组成list数组 java的map和list_链表

单例集合(Collection)

  • 概念:java不提供直接集成Collection类的接口,只能继承其子接口List和Set,存储一组不唯一,无序的对象。

1:List接口

  • List:是一个有序的接口,有索引,可以存储重复的值。
  • Set:唯一,无序的接口,不可以保存重复的值。
  • 区别:存储有序无序,重复不重复,Set删除和插入效率高,元素位置不会发生变化,List有索引,查询快。

1-1:ArrayList

继承AbstractList和实现List(增删改查)。RandomAccess(随机访问),Cloneable(克隆),java.io.Serializable(序列化)这些接口。线程不安全,建议单线程使用。

Java代码的map的value值组成list数组 java的map和list_排序算法_02

  • ArrayList:包含elementDate和size对象。允许空,重复,有序,线程不安全。
transient Object[] elementData; 保存添加的数组。初始容量10,扩容是原始大小的1.5倍。
    删除数据是elementDate的大小是不会改变。理解:扩容的改变需要重新建一个集合。
           
    transient修饰不会序列化。elementDate有扩容。
    加快速度,序列化文件变小。
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioural compatibility with clone()
        s.writeInt(size);

        // Write out all elements in the proper order. 遍历elementDate 
        for (int i=0; i<size; i++) {
            s.writeObject(elementData[i]);
        }

        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }


private int size; 元素的个数,null是一个元素
  • ArrayList删除:System.arraycopy方法整体向前移动一个位置,最后一个位置的元素指定为null,这样让GC可以去回收它。

Java代码的map的value值组成list数组 java的map和list_开发语言_03

  • 优点:实现了RandomAccess(随机访问)接口,查找get很快,末尾添加数据非常快。
  • 缺点:插入和删除是需要涉及一次元素的复制,元素多很耗性能。

1-2:LinkedList

  • 双向链表,每一个节点里存到上下一个节点的地址。
  • 插入和删除快,查找和修改比较慢

 

Java代码的map的value值组成list数组 java的map和list_排序算法_04


  • LinkedList 继承了 AbstractSequentialList 类。
  • LinkedList 实现了 Queue 接口,可作为队列使用。
  • LinkedList 实现了 List 接口,可进行列表的相关操作。
  • LinkedList 实现了 Deque 接口,可作为队列使用。
  • LinkedList 实现了 Cloneable 接口,可实现克隆。
  • LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

1-3:Vector

  • 同步,执行效率不高,所以线程安全,容器扩容为2倍,

2:Set接口

Java代码的map的value值组成list数组 java的map和list_java_05

2-1:HashSet

  • HashSet是基于HashMap来实现的,没有重复数据的接口,允许null,线程不安全,无序。
  • HashSet在存入一个值时,会调用该对象的hashCode()方法来获取其hashCode值。根据hashCode的值来决定该对象在HashSet中储存的位置。判断两个值是否相同需要用equals()来比较。
---封装成同步
SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));

2-2:TreeSet

  • 有序,可排序(equles),不可重复,红黑树。
  • TreeSet是二叉树(红黑树)是实现的,自动排序的,不允许又NULL。
TreeSet<Object> objects = new TreeSet<>();
        objects.add(32);
        objects.add(31);
        objects.add(34);
        System.out.println(objects);
[31, 32, 34]

2-3:LinkedHashSet

  • 会保存添加数据的顺序,非同步,允许空,继承HashSet,底层使用LinkedHashMap。

Java代码的map的value值组成list数组 java的map和list_后端_06

LinkedHashSet<String> lhset = new LinkedHashSet<String>();
 
        // Adding elements to the LinkedHashSet
        lhset.add("Z");
        lhset.add("PQ");
        lhset.add("N");
        lhset.add("O");
        lhset.add("KK");
        lhset.add("FGH");
        System.out.println(lhset);
[Z, PQ, N, O, KK, FGH]
  • HashSet:
  • 不能保证元素的排列顺序,顺序有可能发生变化
  • 集合元素可以是null,但只能放入一个null
  • HashSet底层是采用HashMap实现的
  • HashSet底层是哈希表实现的
  • TreeSet:
  • Treeset中的数据是排好序的,不允许放入null值。
  • TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key。
  • TreeSet的底层实现是采用二叉树(红-黑树)的数据结构。

双列集合(Map)

异常:

  • NoSuchElementException-----当调用的映射中没有元素存在时
  • ClassCastException-------对象与映射中的元素不兼容时
  • NullPointerException-------如果试图使用映射不允许使用的null对象时
  • UnsupportedOperationException-----当试图改变一个不允许修改的映射时

1-1:HashMap

Java代码的map的value值组成list数组 java的map和list_链表_07

  • 是一个散列表,键(键:HashSet)值对形式,无序的,线程不安全,键允许又一个空,非同步。
  • 初始容量为16,加载因子是0.75。

1-2:TreeMap

键排序,非同步,线程不安全,

1-3:LinkedHastMap

  • LinkedHashMap继承自HashMap,它的多种操作都是建立在HashMap操作的基础上的。同HashMap不同的是,LinkedHashMap维护了一个Entry的双向链表,保证了插入的Entry中的顺序。
public class Test{
     public static void main(String[] args) {
      Map<String, String> map = new HashMap<String, String>();
      map.put("1", "value1");
      map.put("2", "value2");
      map.put("3", "value3");
      
      //第一种:普遍使用,二次取值
      System.out.println("通过Map.keySet遍历key和value:");
      for (String key : map.keySet()) {
       System.out.println("key= "+ key + " and value= " + map.get(key));
      }
      
      //第二种
      System.out.println("通过Map.entrySet使用iterator遍历key和value:");
      Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
      while (it.hasNext()) {
       Map.Entry<String, String> entry = it.next();
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
      
      //第三种:推荐,尤其是容量大时
      System.out.println("通过Map.entrySet遍历key和value");
      for (Map.Entry<String, String> entry : map.entrySet()) {
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
    
      //第四种
      System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
      for (String v : map.values()) {
       System.out.println("value= " + v);
      }
     }
}

1-4:HashTable

  • 默认容量11,加载因子0.75,同步,不允许键值null,扩容为2倍-1,不会转换红黑树。