https://baike.baidu.com/item/java%E9%9B%86%E5%90%88%E7%B1%BB/4758922?fr=aladdin

https://www.cnblogs.com/zhuoqingsen/p/8573643.html

集合类存放于java.util包中。

集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。
集合类型主要有3种:set(集)、list(列表)和map(映射)
集合接口分为:Collection和Map,list、set实现了Collection接口

我们为什么要设定不同的集合类型,是为了放置不同的数据,而且不同类型用在不同的场合。这三个类放在何处呢,它们放在java.util包中,Set、List和Map都是接口,它们有各自的实现类。Set的主要实现类:HashSet和TreeSet,List的主要实现类是ArrayList,LinkedList而Map主要实现类是HashMap和TreeMap。

总的说来,Java API中所用的集合类,都是实现了Collection接口,他的一个类继承结构如下:
Collection<--List<--Vector<--Stack
Collection<--List<--ArrayList
Collection<--List<--LinkedList
Collection<--Set<--HashSet
Collection<--Set<--HashSet<--LinkedHashSet
Collection<--Set<--SortedSet<--TreeSet

List 接口及其实现类

  • 有序集合,集合中每个元素都有其对应的顺序索引,类似数组,索引也是从 0 开始,可以根据元素的索引,来访问元素。

  • List 集合允许添加相同的元素,因为它是通过下标来取值的,不会因为元素相同而产生冲突。

  如何应用接口List的一个重要实现类 ArrayList呢?

  1. ArrayList集合类的定义与添加集合元素(不同类型的元素)

  

  2.访问集合元素通过get(集合下标) 获取的是抽象Object对象类型,这里需要强转弱,自动拆箱

  •   String s1=(String)ls.get(0);
  •   int s2=(Integer)ls.get(1);
  •   double s1=(Double)ls.get(2);

  3.删除元素

  ls.remove(1);//删除下标为1的对象

  4.遍历集合元素

  数组遍历是通过游标遍历,List集合类遍历集合元素类似于数组遍历,也可以通过索引遍历,另外List集合类还可以使用Iterator接口遍历集合元素(实际上,所有Collection集合类都可以使用Iterator接口遍历集合元素,因为实现类都实现Iterable<E>接口

  

  • 使用Iterator接口遍历集合元素

  

  5.对元素集合进行排序

  一般有两种方式

  第一种是

  封装类实现了Comparator接口,封装类就是平常的VO/PO类,例如User

  

public class User implements Comparable<User>
{
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAger() {
return age;
}
public void setAge(Integer age) {
this.age= age;
}
public int compareTo(User arg0) {
return this.getAge().compareTo(arg0.getAge());
}
} //测试客户端代码
public static void main(String[] args) {
User user1 = new User();
user1.setName("zhangsan");
user1.setAge(10);
User user2 = new User();
user2.setName("lisi");
user2.setAge(6);
List<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2);
Collections.sort(list); //排序
for(User u : list){
System.out.println(u.getName()); //输出
     } 

    
}
  lisi
 zhangshan

  第二种是封装类没有实现Comparable接口,此时需要在调用sort的另一个有参方法,依旧是这个封装类,但是没有实现Comparable,我这里就不写封装类,同上

  

        User user1 = new User();
user1.setName("zhangsan");
user1.setAge(10);
User user2 = new User();
user2.setName("lisi");
user2.setAge(6);
List<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2); //初始化list
Collections.sort(list,new new Comparator<User >(){ //覆盖排序方法
public int compare(User u1, User u2) {
//按照User的年龄进行升序排列
if(u1.getAge() > u2.getAge()){
return 1;
}
if(u1.getAge() == u2.getAge()){
return 0;
}
return -1;
}
}); //排序

  如何应用Vector?

  Vector与ArrayList在用法上几乎完全相同。但是它是线程安全的,也就是加了同步锁,相比之下性能会显得慢一些

  那么在多线程下的ArrayList怎么样?

  两个线程同时访问,对容器的同一位置进行了同一时刻的赋值,则会达不到希望容器产生的效果,比如

  •   循环10000次在多线程可能会小于100000次
  •   在ArrayList扩容的时候会造成数组越界,产生非常诡异的异常

  Set接口及其实现类

  Set集合类特点是什么?

  • 无序集合

  • 不允许包含重复元素,根据equals方法判断两个对象相同

  如何应用Set接口的一个重要实现类HashSet呢

  1.HashSet集合类的定义与添加集合元素

  • HashSet集合添加一个元素时,会先得到该对象的hashCode值,然后通过equals方法判断集合内是否已存在相同的对象,如果已存在相同的对象,即hashcode指向的内存地址相同,则无法添加该对象。String字符串重写了equals方法,虽然str1(小明)与str2(小张)是两个不同的对象,但str1.equals(str2);返回是false,因此添加str2失败。
  • HashSet是先比较元素的HashCode的值,也就是哈希值,如果哈希值相同的情况下,会调用equals方法比较两个元素的值是否相同。
  • Set的另外一个实现类TreeSet则是通过调用CompareTo的方法,如果返回值为0,证明两个元素相同,因此TreeSet其实是一个有序的集合。

  2.遍历集合元素

  • HashSet集合只能通过Iterator接口或者增强for循环遍历集合元素,且因为HashSet不能保证元素的排列顺序,因而遍历读取集合元素的顺序是有可能发生变化的

//增强for的方式
for(Person p:set){
System.out.println(p.name+p.age);
}

  3.删除元素

  • set.remove(p1);

  Map接口及其实现类

    Map集合的特点是什么?

  • 双列集合,保存两组值,一组是键key,另一组是值value,key和value之间存在单向一对一关系,通过指定的key,总能找到唯一的、确定的value
  • Map集合类的key不允许重复,根据equals方法判断两个key相同

  • Map集合类的key和value可以是任何类型的数据(键和值都可以为null)

  如何应用HashMap?

  • HashMap集合类添加键值对时,先根据equals方法判断要添加键值对的key是否存在,如果存在,value会发生覆盖,如果不存在,添加新的键值对。

  遍历集合元素

  1.keySet()方法获取元素

  原理:

  • 将Map集合中的所有键(Key)存入到Set集合中,因为Set集合具备迭代器,所以可以用迭代方式取出所有的键,再根据get方法获取每一个键对应的值。简单说就是:Map集合---->Set集合 ---->迭代器取出

  2.entrySet()方法获取元素:

  原理:

  • 将Map集合中的映射关系(Key-Value)存入到了Set集合中,而这个映射关系的数据类型是Map.Entry,在通过迭代器将映射关系存入到Map.Entry集合中,并通过其中的getKey()和getValue()放取出键值。

  其余还有其他遍历方式,比如说增强for,但是前提都是要获得Set存储Key的集合,即调用map.KeySet(),然后转化为String,在通过getValue("Key")的方式获取值,在实际开发当中比如获取数据库查询回来的ResultSet 都是rs,getString("字段名)

  • 遍历得到结果的顺序并不是添加顺序,实际上,Map里的key和Set集合的存储形式(无序)类似,与HashSet集合不能保证元素的顺序一样,HashMap也不能保证其中key-value键值对的顺序。

  删除集合元素

  map.remove(key);

  集合类之间的几种比较(小结)

  1.Vector、ArrayList、LinkedList的异同?分别适用于何种需求?

ArrayList和Vector都是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许通过顺序索引查找元素,但是插入数据、删除数据要设计到数组元素移动等内存操作,所以查找数据快、增删数据慢。ArrayList和Vector在用法上几乎相同,但有一点明显区别:ArrayList是线程不安全的,多线程情况下,需要写代码保证集合的同步性;Vector是线程安全的,它使用了synchronized方法保证了多线程情况下集合的同步性;也正因为Vector的线程安全,它在性能上比ArrayList差。

LinkedList,首先它是一个List集合,可以根据索引来随机访问集合中的元素,这个与ArrayList的用法相同。除此之外,LinkedList采用双向链表实现存储,查找数据时需要进行向前或向后遍历,直到找到索引数据;但是插入数据时只需要记录本项的前后项即可,所以查找数据慢、增删数据快。

Arraylist 底层使用的是Object数组;LinkedList 底层使用的是双向链表数据结构(注意双向链表和双向循环链表的区别)

ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)

适用需求建议:

  • 需要经常遍历集合元素,建议使用ArrayList、Vector
  • 需要经常执行插入、删除操作来改变集合的大小,建议使用LinkedList
  • 多线程的情况下,可以考虑Vector。但也可以考虑ArrayList,另外写代码保证集合的同步性
  • 关于CopyOnWriteArrayList也是一个线程安全的容器,原理是

  CopyOnWriteArrayList底层就是数组,加锁就交由ReentrantLock来完成。

  在添加的时候就上锁,并复制一个新数组,增加操作在新数组上完成,将array指向到新数组中,最后解锁。

  在修改时,复制出一个新数组,修改的操作在新数组中完成,最后将新数组交由array变量指向。

  写加锁,读不加锁

  2.HashSet与TreeSet的异同?分别适用于何种需求?

HashSet与TreeSet相同点:都是Set接口的实现类,集合元素都不允许重复;

HashSet与TreeSet不同点:

HashSet中的数据是无序的,可以放入null,且只能放入一个null,通过计算元素的hashCode值快速操作,所以HashSet的效率很高。

TreeSet中的数据是自动排序的,这个有序不同于List接口那样按照插入的先后顺序而且有对应的索引,这个顺序是按照元素对象自己定义的排序规则而定的。默认情况下,TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列,基于TreeMap。因此,TreeSet中的每个对象的类都必须实现Comparable接口定义排序规则才可以正常使用,如String等这些类本身已经实现Comparable接口并有默认顺序,而null没有实现Comparable接口,所以TreeSet不允许放入null值。

  3.HashMap、TreeMap、HashTable的异同?分别适用于何种需求?

HashMap和HashTable的关系类似于ArrayList和Vector的关系,HashTable与HashMap的用法基本相同,两者的区别有:

HashMap允许有空键(null)与空值(null),非线程安全,效率较高;

Hashtable不允许有空键(null)与空值(null),线程安全,效率较低;

TreeMap与HashMap的关系也类似与TreeSet和HashSet的关系,TreeMap实现SortMap接口,能够把它保存的键值对根据key排序,基于红黑树,从而保证TreeMap中所有键值对处于有序状态。TreeMap要求所有的key必须实现Comparable接口,默认遵循key的默认排序规则,也可以指定排序的比较器。当用Iterator 遍历TreeMap时,得到的记录是排过序的(类似TreeSet),不允许有空键(null)。

  by the way

  fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。抛java.util.ConcurrentModificationException

java的集合类【Map(映射)、List(列表)与Set(集)比较】的更多相关文章

  1. java之集合类特性对比分析列表

    类集合框架有很多文章都列出了继承关系图,但是我没有找到更清晰的特性对比图,我这里根据使用选择条件总结对比罗列一下它们之间的一些特点.

  2. Reactor系列(五)map映射

    #java# #reactor# #flux# #map# #映射# 视频解视: https://www.bilibili.com/video/av79179444/ FluxMonoTestCase ...

  3. Java精选笔记_集合【Map(映射)接口】

    Map(映射)接口 简介 该集合存储键值对,一对一对的往里存,并且键是唯一的.要保证map集合中键的唯一性. 从Map集合中访问元素时,只要指定了Key,就能找到对应的Value. 关键字是以后用于检 ...

  4. Map java中的map 如何修改Map中的对应元素

    Map java中的map 如何修改Map中的对应元素 Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象.         Map的接口         Map ...

  5. 115个Java面试题和答案——终极列表(上)

    本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力.下面的章节分为上下两篇,第一篇将要讨论面向对象编程和它的特点,关于Java和它的功能 ...

  6. 转:115个Java面试题和答案——终极列表(上)

    转自:http://www.importnew.com/10980.html 本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力.下面的 ...

  7. 115个Java面试题和答案——终极列表

    from http://www.importnew.com/10980.html#collection http://www.importnew.com/11028.html 下面的章节分为上下两篇, ...

  8. 115个Java面试题和答案——终极列表(上)【转】

    本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力.下面的章节分为上下两篇,第一篇将要讨论面向对象编程和它的特点,关于Java和它的功能 ...

  9. (7)Java数据结构--集合map,set,list详解

    MAP,SET,LIST,等JAVA中集合解析(了解) - clam_clam的专栏 - CSDN博---有颜色, http://blog.csdn.net/clam_clam/article/det ...

随机推荐

  1. mysql学习之基础篇08 UTF8编码

    这次我们来说一下在Mysql中的编码问题: 我们知道应用于计算机的最早的字符集是ASCII,它所组成的编码是ASCII编码:由于对于其他国家来说它所容纳的字符个数比较少,后来就出现了ANSI字符集,它 ...

  2. CPNtools 模拟工具适合分析什么样的协议

    最近梳理和CPNtools和Scyther之间的性能和差别.方便后面整理使用 1.库所的托肯值是什么? 托肯值也叫作令牌, 即网络系统中的资源,托肯的数目值代表了网络赋予的资源大小.在一个活的网络系统 ...

  3. Elasticsearch 7.x - IK分词器插件(ik_smart,ik_max_word)

    一.安装IK分词器 Elasticsearch也需要安装IK分析器以实现对中文更好的分词支持. 去Github下载最新版elasticsearch-ik https://github.com/medc ...

  4. Keras实现Self-Attention

    本文转载自:https://blog.csdn.net/xiaosongshine/article/details/90600028 一.Self-Attention概念详解 对于self-atten ...

  5. 剑指Offer(三十六):两个链表的第一个公共结点

    剑指Offer(三十六):两个链表的第一个公共结点 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.ne ...

  6. 剑指Offer(三十三):丑数

    剑指Offer(三十三):丑数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_31 ...

  7. vue之获取原生的dom的方式

    1.获取原生的DOM的方式 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  8. Java - 框架之 SpringMVC

    一. 简单配置 (XML) 1. web.xml <?xml version="1.0" encoding="UTF-8"?> <web-ap ...

  9. ES安装手册

    http://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.htmlhttps://githu ...

  10. DP斜率优化总结

    目录 DP斜率优化总结 任务安排1 任务计划2 任务安排3 百日旅行 DP斜率优化总结 任务安排1 首先引入一道题,先\(O(N^2)\)做法:分别预处理出\(T_i,C_i\)前缀和\(t[i],c ...