Map、Set、List集合差别及联系详解

Stella981
• 阅读 432

前言:

数组Array和集合的区别:

1、数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型)

2、JAVA集合可以存储和操作数目不固定的一组数据。

3、若程序时不知道究竟需要多少对象,需要在空间不足时自动扩增容量,则需要使用容器类库,array不适用。 

注:使用相应的toArray()和Arrays.asList()方法可以相互转换。

集合:

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

集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用。

集合类型主要有三种:set(集)、list(列表)、map(映射)。

Map、Set、List集合差别及联系详解

一、Collection接口

Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素。Java SDK提供的类都是继承自Collection的“子接口”如List和Set。

如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:

Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
  Object obj = it.next(); // 得到下一个元素
}

由Collection接口派生的两个接口是List和Set。

二、Set

Set接口同样是Collection接口的一个子接口,Set不包含重复的元素。

HashSet:使用hashmap的一个集的实现。虽然集定义成无序,但必须存在某种方法能高效地找到一个对象。使用一个hashmap对象实现集的存储和检索操作时在固定时间内实现的。

TreeSet:在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap。

为优化hashset空间的使用,可以调优初始容量和负载因子。TreeSet 不包含调优选项,因为树总是平衡的,保证了插入、删除、查询的性能的高效。

当您要从集合中以有序的方式抽取元素时,TreeSet实现会有用处。为了能顺利进行,添加到TreeSet的元素必须是可排序的。 

import java.util.*;
public class SetExample {
      public static void main(String args[]) {
          Set set = new HashSet();
          set.add("Bernadine");
          set.add("Elizabeth");
          set.add("Gene");
          set.add("Elizabeth");
          set.add("Clara");
          System.out.println(set);

          Set sortedSet = new TreeSet(set);
          System.out.println(sortedSet);
      }
}

[Gene, Clara, Bernadine, Elizabeth]
[Bernadine, Clara, Elizabeth, Gene]

三、List

List接口继承了Collection接口,定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。

实际上有两种list:一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的LinkedList,它并不是快速随机访问设计的,而是具有更通用的方法。

List : 次序是List最重要的特点:它保证维护元素特定的顺序。

ArrayList : 由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。

LinkedList : 对顺序访问进行了优化,向List中间插入与删除的开销并不大,随机访问则相对较慢。还具有下列方法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。

Vector:实现一个类似数组一样的表,自动增加容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中一样。你也可以用一个迭代器从一个Vector中检索对象Vector是唯一的同步容器类!!

stack:这个类从vector派生而来,并增加了方法实现栈,一种后进先出的存储结构。

List的用法示例:

package collection;

import java.util.*;

public class SetExample {
    public static void main(String[] args) {
        List linkedList = new LinkedList();
        for (int i = 0; i <= 5; i++) {
            linkedList.add("a"+i);
        }
        System.out.println(linkedList);
        linkedList.add(3,"a100");
        System.out.println(linkedList);
        linkedList.set(6,"a200");
        System.out.println(linkedList);
        System.out.println(linkedList.get(2));
        System.out.println(linkedList.indexOf("a3"));
        linkedList.remove(1);
        System.out.println(linkedList);
    }
}

Map、Set、List集合差别及联系详解

四、list和set对比

Set子接口:无序,不允许重复,检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List子接口:有序,可以有重复元素,和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

Set和List具体子类:
    Set
     |————HashSet:以哈希表的形式存放元素,插入删除速度很快。

    List
     |————ArrayList:动态数组
     |————LinkedList:链表、队列、堆栈。

五、map

map接口不是Collection接口的继承。

不重复的键到值的映射。

Map.Entry 接口

map的entrySet()方法返回一个实现map.entry接口的对象集合。集合中每个对象都是底层map中一个特定的键值对。

HashMap 类和 TreeMap 类

在map中插入、删除和定位元素,HashMap是最好的选择。但如果您要按顺序遍历键,那么TreeMap 会更好。根据集合大小,先把元素添加HashMap,再把这种映射转换成一个用于有序键遍历的TreeMap 可能更快。

为了优化hashmap空间的使用,您可以调优初始容量和负载因子。这个treeMap没有调优选项,因为该树总处于平衡状态。

hashtable:实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类时前面Java实现的一个继承,并且通常能在实现映象的其它类中更好地使用。

hashmap:实现一个映象,运行存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个空)。

WeakHashMap:如果有一个键对于一个对象而言不再被引用,键将被舍弃,WeakHashMap在具有大量数据时使用。

TreeMap: 实现这样一个映象,对象是按键升序排列的。

map的使用示例:

以下程序演示了具体map类的使用。该程序对自命令行传递的词进行频率计数。hashmap起初用于数据存储。后来,映射被转换为TreeMap以显示有序的键列列表。

package collection;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class MapExample {
    public static void main(String[] args) {
        String[] array = {"a","b","c","d","e"};
        Map map = new HashMap();
        Integer ONE = new Integer(1);
        for (int i=0, n=array.length; i<n; i++) {
            String key = array[i];
            int frequency = i+1;
            map.put(key, frequency);
        }
        System.out.println(map);
        Map sortedMap = new TreeMap(map);
        System.out.println(sortedMap);
        //hashmap的同步
        Map map1 = Collections.synchronizedMap(map);
        System.out.println(map1);
    }
}

结果:

Map、Set、List集合差别及联系详解

六、解惑:

1、什么是iterator

对集合的遍历,遍历的时候不建议修改集合。

2、Iterator与ListIterator有什么区别?

Iterator:只能正向遍历集合

ListIerator:继承Iterator,可以双向列表遍历

3、HashMap与HashTable有什么区别?

HashMap允许空值作为键或值,不同步的,迭代时采用的是快速失败机制

HashTable不允许空值,同步的

注:有多线程的可能时,使用hashtable,反之使用hashmap。非线程安全的数据结构能带来更好地性能。

如果将来有可能需要按顺序获取键值对,hashmap是更好地选择,因为hashmap的一个子类LinkedHashMap。

如果多线程时使用hashmap,Collections.synchronizedMap()可以代替,总的来说HashMap更灵活。

4、在Hashtable上下文中同步是什么意思?

同步意味着在一个时间点只能有一个线程可以改变哈希表,任何线程在执行hashtable的更新操作前需要获取对象锁,其它线程等待锁的释放。

5、为什么Vector不推荐使用?

使用时ArrayList优先于Vector,Vector是同步的,性能会低一些,如果迭代一个vector,还要加锁,以避免其他线程同一时刻改变集合,加锁效率更慢。

江疏影讲Java@目录

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java8新特性
Stream将List转换为Map,使用Collectors.toMap方法进行转换背景:User类,类中分别有id,name,age三个属性。List集合,userList,存储User对象1、指定keyvalue,value是对象中的某个属性值。 Map<Integer,StringuserMap1userList.str
Wesley13 Wesley13
3年前
java集合框架
一、为什么要使用集合单个数据,可以用变量保存;多个数据,可以用数组保存;但是对于存储多个数据且数量不确定的情况,使用集合;二、集合和数组的区别(1)数组:1、只能保存同一种类型的数据;2、数组一旦创建,容量不可改变;3、数组可以保存引用类型的数据和基本类型的数据;(2)集合:1、可以保存不同类型的数据;2
Wesley13 Wesley13
3年前
Java中Map,List与Set的区别
首先,数组和集合的区别:数组是大小固定的集合可以存储和操作数目不固定的一组数据,集合只能存放引用类型的的数据,不能存放基本数据类型特性List允许重复有序继承自ConnectionSet不允许重复无序继承自Connection
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable