1.Set接口

集合中的元素不能重复,所以存入Set的元素都必须定义equals()来确保对象的唯一性。

无序、无索引

1.1HashSet类

实现了Set接口,此实现不是同步的

由哈希表支持。实际上是一个HashMap集合。

不能保证迭代顺序和存储顺序一致。特别是它不保证该顺序恒久不变。

保证元素唯一的方式:hashCode()和equals()(若为自定义类,需重写两个方法)。

假定哈希函数将这些元素正确地分布在桶中。对此 set 进行迭代所需的时间与 HashSet 实例的大小(元素的数量)和底层 HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。

1.1.1哈希表

底层使用数组机制。

数组中存放对象

由对象的特有数据结合相应的算法(Object中为hashCode()),计算出此对象在数组中的位置。

哈希冲突

2个对象计算出的hashCode()结果一样。

则调用此对象的equals(),判断两个对象是否一样。

  • 一样,不存第二个,
  • 不一样,存

1.2TreeSet

使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

此实现为基本操作(addremovecontains)提供受保证的 log(n) 时间开销。

此实现不是同步的。

1.2.1构造方法

TreeSet(Collection<T> coll):构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。

1.2.1方法

E   last(): 返回此 set 中当前最后一个(最高)元素。

E  first():返回此 set 中当前第一个(最低)元素。

1.3LinkedHashSet

HashSet的子类。

数据存储结构:链表+哈希表

保证元素的存取和取出顺序一致。

2.List接口

有序的 collection(也称为序列)。

此接口的用户可以对列表中每个元素的插入位置进行精确地控制。

用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

通常允许重复的元素。列表通常允许满足 e1.equals(e2) 的元素对 e1 和 e2,并且如果列表本身允许 null 元素的话,通常它们允许多个 null 元素。

ListIterator listIterator() :返回此列表元素的列表迭代器(按适当顺序)。

2.1 ArrayList

List 接口的大小可变数组的实现.

此类大致上等同于 Vector 类,除了此类是不同步的

每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。并未指定增长策略的细节。

在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

2.1.1构造方法

ArrayList():构造一个初始容量为 10 的空列表。

ArrayList(Collection<E> coll): 构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。

ArrayList(int initialCapacity);构造一个具有指定初始容量的空列表。

2.1.2常用方法

boolean add(E e):将指定的元素添加到此列表的尾部

void add(int index,E e):将指定的元素插入此列表中的指定位置。原位置元素后移。

boolean add(int index,Collection<E> coll):从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。

E remove(int index):移除此列表中指定位置上的元素。并返回被删除的元素。

E set(int index,E e):用指定的元素替代此列表中指定位置上的元素。返回此位置上的原元素。

  • ArrayList的contains()方法源码:
public boolean contains(Object o){return indexOf(o)>=0;
}

2.2LinkedList

List 接口的链接列表实现。

采用双向列表实现的,对数据的索引需要从列表头开始遍历,随机访问效率低;插入元素时不需要对数据进行移动,所以插入效率高。LinkedList是非线程安全的容器。

此类实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。

此实现不是同步的

2.2.1构造方法

LinkedList():构造一个空的列表。

LinkedList(Collection<E> coll):构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代器返回的顺序排列。

2.2.2 方法

E peek():获取但不移除此列表的头(第一个元素)。

E peekFirst():获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。

E peekLast():获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。

E poll():获取并移除此列表的头(第一个元素)——E pollFirst()、E pollLast()

E pop():从此列表所表示的堆栈处弹出一个元素。

void push(E e): 将元素推入此列表所表示的堆栈。

boolean offer(E e): 将指定元素添加到此列表的末尾(最后一个元素)。——boolean offerFirst()、boolean offerLast()

2.3 Vector

可以实现可增长的对象数组。Vector同步的

与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。

每个向量会试图通过维护 capacitycapacityIncrement 来优化存储管理。

  • capacity 始终至少应与向量的大小相等;这个值通常比后者大些,因为随着将组件添加到向量中,其存储将按 capacityIncrement 的大小增加存储块。
  • 应用程序可以在插入大量组件前增加向量的容量;这样就减少了增加的重分配的量。

2.3.1构造方法

Vector():构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。

Vector(Collection<E> coll):构造一个包含指定 collection 中的元素的向量,这些元素按其 collection 的迭代器返回元素的顺序排列。

Vector(int initialCapacity):使用指定的初始容量和等于零的容量增量构造一个空向量。

Vector(int initialCapacity, int capacityIncrement):使用指定的初始容量和容量增量构造一个空的向量。

2.3.2方法

void copyInto(Object[] obj):将此向量的组件复制到指定的数组中。

void trimTosIZE():对此向量的容量进行微调,使其等于向量的当前大小。

取出方法:枚举Enumeration

没有一个ArrayList的方法是同步的,而Vecotr的绝大多数方法(例如,add、insert、remove、set、equals、hashCode等)都是直接或间接同步的,所以Vector是线程安全的,ArrayList不是线程安全的。性能上ArrayList较好。

2.4总结

  • 主要操作为:索引、只在集合末尾增删元素——使用ArrayList和Vector
  • 主要操作为:指定位置的插入删除——LinkedList
  • 多线程——Vector

3.Map接口

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

Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。

某些映射实现可明确保证其顺序,如 TreeMap 类;另一些映射实现则不保证顺序,如 HashMap 类。

所有通用的映射实现类应该提供两个“标准的”构造方法:

  • 一个 void(无参数)构造方法,用于创建空映射;
  • 一个是带有单个 Map 类型参数的构造方法,用于创建一个与其参数具有相同键-值映射关系的新映射。
  • 实际上,后一个构造方法允许用户复制任意映射,生成所需类的一个等价映射。
  • 尽管无法强制执行此建议(因为接口不能包含构造方法),但是 JDK 中所有通用的映射实现都遵从它。

3.1方法

boolean containsKey(Object key):如果此映射包含指定键的映射关系,则返回 true。

boolean containsVlue(Object value): 如果此映射将一个或多个键映射到指定值,则返回 true。

Set<Map,Entry<K,V>> enctrySet():返回此映射中包含的映射关系的 Set 视图。

V get(Object key): 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null

Set<K> getKey(): 返回此映射中包含的键的 Set 视图。

V put(K key,V value):  将指定的值与此映射中的指定键关联(可选操作)。

Collections<V> values(): 返回此映射中包含的值的 Collection 视图。

3.2Map集合的遍历

3.2.1键找值的方式

Set<String> keySet=map.keySet();Iterator<String> it=keySet.iterator();while(it.hasNext()){String key=it.next();String value=map.get(key);
}

3.2.2 Entry键值对对象

Entry:Map的内部类

将键值对封装成了对象,可以从每个键值对对象获取对应的键和值。

步骤:

  1. 获取Map集合中,所有键值对(Entry)对象,以Set集合形式返回
  2. 遍历包含键值对对象的Set集合,得到每一个键值对对象
  3. 通过键值对对象,获取对象中的键与值。
Set<Map.Entry<String,String>> entrySet=map.entrySet();Iterator<Map.Entry<String,String>> it=entrySet.iterator();while(it.hasNext()){Map.Entry<String,String> entry=it.next();String key=entry.getKey();String value=entry.getValue();
} 

Map集合不能使用增强for进行遍历,但转成Set后就可使用。

3.3HashMap

基于哈希表的 Map 接口的实现。此实现不是同步的。

允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)

此类不保证映射的顺序。

HashMap 的实例有两个参数影响其性能:初始容量 和加载因子。

  • 容量 是哈希表中桶的数量,
  • 初始容量只是哈希表在创建时的容量。
  • 加载因子 (默认是0.75)是哈希表在其容量自动增加之前可以达到多满的一种尺度。
  • 当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。

3.3.1构造方法

HashMap():构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。

HashMap(int initialCapacity):构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。

HashMap(int intialCapacity,float loadFactor): 构造一个带指定初始容量和加载因子的空 HashMap。

HashMap(Map<K,V> m):构造一个映射关系与指定 Map 相同的新 HashMap。

3.3.2 HashMap添加元素

当新增加的key的hash值已存在于HashMap中时,会产生冲突。一般而言,对于不同的Key值可能会得到相同的hash值,所以应对冲突进行处理。处理冲突的方法:

  • 开放地址法;
  • 再hash法;
  • 链地址法。

3.3.3HashMap使用链地址法解决冲突的具体操作

3.3.4 向HashMap中添加元素时,若遇到冲突,解决方式如图

Object类的equals()比较规则:当参数obj引用的对象与当前对象为同一个对象时,就返回true,否则返回false。

hashCode()会返回对象存储的内存地址。

为了实现向HashMap中添加键值对,可以根据对对象的内容来判断两个对象是否相等,就需重写hashCode()和equals()。

import java.util.*;class Person{String id;String name;public int hachCode() {return id.hashCode();}public Person(String id,String name) {this.id=id;this.name=name;}public String toString() {return "id="+id+",name="+name;}public boolean equals(Object obj) {Person p=(Person)obj;if(p.id.equals(this.id))return true;elsereturn false;}
}public class Test{public static void test() {System.out.println("Use String as key:");HashMap<Person,String> hm=new HashMap<Person,String>();Person p1=new Person("111","name1");Person p2=new Person("222","name2");hm.put(p1,"address1");hm.put(p2,"address2");Iterator iter=hm.entrySet().iterator();while(iter.hasNext()) {Map.Entry entry=(Map.Entry)iter.next();Person key=(Person)entry.getKey();String val=(String)entry.getValue();System.out.println("key:"+key+",value:"+val);}}public static void main(String[] args) {test();}
}

运行结果

Use String as key:
key:id=111,name=name1,value:address1
key:id=222,name=name2,value:address2

使用自定义类作为HahsMap的key时,需注意:

  1. 若要根据对象的相关属性来定义对象是否相等,需要重写equals方法,一旦重写了equals(),就得重写hashCode();
  2. 当自定义类的多项作为HashMap(HashTable)的key时,最好把这个类设为不可变类;
  3. 从HashMap的工作原理可以看出,如果两个对象相等,那么这两个对象有着相同的hashCode,反之则不成立

3.3.5总结

根据键的hashCode值存储数据,由键可以很快得到它的值,访问速度快。

存的键值对没有固定顺序,取出时是随机的。

适合在Map中插入、删除和定位元素。

采用“强引用”,只有这个key从HashMap中删除后,才能被垃圾回收器回收。

使用最多的。

3.4TreeMap

基于红黑树(Red-Black tree)的 NavigableMap 实现。此实现不是同步的。

实现了SortMap接口,能够将记录根据键值对排序保存,取出来时是排好序后的键值对。适用于需要按自然顺序或自定义顺序遍历键。

该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。

此实现为 containsKey、get、put 和 remove 操作提供受保证的 log(n) 时间开销

3.4.2构造方法

TreeMap():使用键的自然顺序构造一个新的、空的树映射。

TreeMap(Comparator< K> comparator):构造一个新的、空的树映射,该映射根据给定比较器进行排序。

TreeMap(Map<K,V> m):构造一个与给定映射具有相同映射关系的新的树映射,该映射根据其键的自然顺序 进行排序。

TreeMap((SortedMap<K,V> m):构造一个与指定有序映射具有相同映射关系和相同排序顺序的新的树映射。

3.4.3方法

Map.Entry<K,V> ceilingEntry(K key):返回一个键-值映射关系,它与大于等于给定键的最小键关联;如果不存在这样的键,则返回 null

K ceilingKey(K key):返回大于等于给定键的最小键;如果不存在这样的键,则返回 null

Map.Entry<K,V> higherEntry(K key):返回一个键-值映射关系,它与严格大于给定键的最小键关联;如果不存在这样的键,则返回 null

K higherKey(K key):返回严格大于给定键的最小键;如果不存在这样的键,则返回 null

lowerKey()、lowerEntry()

3.5 LinkedHashMap

HashMap的一个子类,按读取顺序排列,适用于需要输入与输出顺序相同。

Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现不是同步的

使用它可以生成一个与原来顺序相同的映射副本,而与原映射的实现无关:

void foo(Map m) {Map copy = new LinkedHashMap(m);...
}

提供特殊的构造方法来创建链接哈希映射,该哈希映射的迭代顺序就是最后访问其条目的顺序,从近期访问最少到近期访问最多的顺序(访问顺序)。这种映射很适合构建 LRU 缓存。

3.5.1构造方法

LinkedHashMap():构造一个带默认初始容量 (16) 和加载因子 (0.75) 的空插入顺序 LinkedHashMap 实例

LinkedHashMap(int initialCapacity,int loadFactor,boolean accessOrder):构造一个带指定初始容量、加载因子和排序模式的空 LinkedHashMap 实例。

3.6 WeakHashaMap

与HashMap类似,key采用“弱引用”的方式,在 WeakHashMap 中,当某个键不再正常使用时,将自动移除其条目,被垃圾回收器回收。

  • 对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。
  • 丢弃某个键时,其条目从映射中有效地移除。

WeakHashMap 中的值对象由普通的强引用保持

null 值和 null 键都被支持。

该类具有与 HashMap 类相似的性能特征,并具有相同的效能参数初始容量 和加载因子。

不同步的

3.7Hashtable

此类实现一个哈希表,该哈希表将键映射到相应的值。

任何非 null 对象都可以用作键或值。

为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。

3.7.1构造方法

Hashtable():用默认的初始容量 (11) 和加载因子 (0.75) 构造一个新的空哈希表。

3.7.2方法

Enumeration<K> keys():返回此哈希表中的键的枚举。

3.7.3示例

它将数字的名称用作键:

​   Hashtable<String, Integer> numbers = new Hashtable<String, Integer>();numbers.put("one", 1);numbers.put("two", 2);numbers.put("three", 3);​

要获取一个数字,可以使用以下代码:

Integer n = numbers.get("two");
if (n != null) {System.out.println("two = " + n);
}

3.8HashMap和HashTable

HashMap Hashtable
是Hashtable的轻量级实现(非线程安全的实现) 效率上,HashMap高于Hashtable
都完成了Map接口 都完成了Map接口
允许空键值(key为null),最多只允许一条记录的键为null 不允许
去掉了Hashtable的contains方法,改成containsvalue和containsKey  
java 1.2引进的Map interface的一个实现 继承自Dictionary类
不支持线程同步,所以不是线程安全的 线程安全的
使用Iterator 使用Enumeration
hash数组默认大小是16,而且一定是2的指数 hash默认大小是11,增加方式是old*2+1;
hash值的使用不同 Hashtable使用对象的hashCode

使用自定义类型作为HashMap或Hashtable的key需注意:

  • 不能存储重复的键,当有重复的键时,不会创建新的映射关系,而是使用先前的键值;
   

集合-2(Set(HashSet、TreeSet、LinkedHashSet)、List(ArrayList、LinkedList、Vector)、Map(HashMap、TreeMap...))相关推荐

  1. Set集合[HashSet,TreeSet,LinkedHashSet],Map集合[HashMap,HashTable,TreeMap]

    ------------ Set ------------------- 有序: 根据添加元素顺序判定, 如果输出的结果和添加元素顺序是一样 无序: 根据添加元素顺序判定,如果输出的结果和添加元素的顺 ...

  2. ArrayList,LinkedList,Vector的异同点

    先总结下ArrayList和LinkedList的区别: 1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. 2.对于随机访问get和set,ArrayLi ...

  3. ArrayList, LinkedList, Vector - dudu:史上最详解

    ArrayList, LinkedList, Vector - dudu:史上最详解 我们来比较一下ArrayList, LinkedLIst和Vector它们之间的区别.BZ的JDK版本是1.7.0 ...

  4. ArrayList ,LinkedList,Vector,StringBuilder,StringBuffer ,String,HashMap,LinkedHashMap,TreeMap

    ArrayList ,LinkedList,Vector 区别和联系 从上面的类层次结构图中,我们可以发现他们都实现了List接口,它们使用起来非常相似.区别主要在于它们各自的实现,不同的实现导致了不 ...

  5. Java容器---Set: HashSet TreeSet LinkedHashSet

    1.Set接口概述        Set 不保存重复的元素(如何判断元素相同呢?).如果你试图将相同对象的多个实例添加到Set中,那么它就会阻止这种重复现象. Set中最常被使用的是测试归属性,你可以 ...

  6. StringBuffer、StringBuilder、ArrayList、Vector、HashMap、HashTable 的扩容机制

    1. StringBuffer.StringBuilder 的扩容机制 StringBuffer.StringBuilder,默认初始化是 16 个字符,默认增容为 原长度+2 → 扩容后:2*(n+ ...

  7. Day48(List接口,ArrayList,LinkedList,Vector,Set接口,HashSet,LinkedHashSet,TreeSet,自然排序,定制排序)

    Collection子接口之一:List接口 List接口概述 鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组 List集合类中元素有序.且可重复,集合中的每个元素都有其对应的顺 ...

  8. java hashset 源码_Java集合源码分析-HashSet和LinkedHashSet

    前两篇文章分别分析了Java的ArrayList和LinkedList实现原理,这篇文章分析下HashSet和LinkedHashSet的源码.重点讲解HashSet,因为LinkedHashSet是 ...

  9. 源码分析-HashSet、LinkedHashSet

    基本特性 HashSet的是依靠组合一个HashMap实现的.然后讲大部分任务都委托给HashMap完成.  当然,HashSet不保证迭代顺序与添加顺序相同,而且也不保证其顺序不变.允许空元素.  ...

  10. 集合之Collection家族的 List接口+LinkedList+Vector+Stack及Set接口+HashSet+LinkedHashSet+TreeSet

    集合之Collection家族的 List接口+LinkedList+Vector+Stack及Set接口+HashSet+LinkedHashSet+TreeSet 一.LinkedList 1.L ...

最新文章

  1. FPGA最全科普总结
  2. linux添加域名证书,在Linux服务器上手动安装免费的Let's Encrypt域名证书 - 乐道主机...
  3. 用pycharm写python_使用Pycharm编写第一个python程序
  4. “光纤之父”高锟离世,感谢他的贡献
  5. exp中query的使用方法
  6. python json unicode_python2下解决json的unicode编码问题
  7. 世界上最诡异的画,到底为何让无数人闻风丧胆?
  8. Python 获取系统信息模块psutil(转载)
  9. 混凝土静力受压弹性模量试验计算公式_C50混凝土静力受压弹性模量试验报告
  10. vivado下载失败并报 End of startup status:LOW
  11. 电脑系统没有自带的字体-楷体GB2312字体 免费版提供下载
  12. lua——牛牛牌型处理相关算法(下)——牌型比较
  13. 打印纸张计算机耗材,耗材相关:与打印机产生故事的常用纸类型
  14. css中margin和padding设置成百分比时参照物是谁
  15. Unity 调用DLL
  16. 数据存储- 存储文件概述
  17. yii2项目实战-博客管理平台的搭建
  18. 有两种人,看似“缺心眼”,实际“聪明绝顶”,堪称“大智若愚”
  19. 古墓里出土的那些奇怪文物,能否证明穿越的存在?
  20. 高铁动车入库 铁警携犬巡逻检查

热门文章

  1. 屏蔽浏览器退格键页面后退
  2. ytu 2335: 0-1背包问题
  3. Spring AOP根据JdbcTemplate方法名动态设置数据源
  4. WinForm窗体缩放动画
  5. 企业CIO如何让IT部门成为价值中心
  6. 算法与数据结构(一)
  7. linux分区合并不损坏系统,更改磁盘分区后修复GRUB启动
  8. reactjs通过lazy函数配合import函数动态加载路由组件
  9. Minio分布式集群示例:8个节点,每节点1块盘
  10. 【收藏】wsl2 出现 Vmmem内存占用过大问题解决