User-Profile-Image
hankin
  • 5
  • Java
  • Kotlin
  • Spring
  • Web
  • SQL
  • MegaData
  • More
  • Experience
  • Enamiĝu al vi
  • 分类
    • Zuul
    • Zookeeper
    • XML
    • WebSocket
    • Web Notes
    • Web
    • Vue
    • Thymeleaf
    • SQL Server
    • SQL Notes
    • SQL
    • SpringSecurity
    • SpringMVC
    • SpringJPA
    • SpringCloud
    • SpringBoot
    • Spring Notes
    • Spring
    • Servlet
    • Ribbon
    • Redis
    • RabbitMQ
    • Python
    • PostgreSQL
    • OAuth2
    • NOSQL
    • Netty
    • MySQL
    • MyBatis
    • More
    • MinIO
    • MegaData
    • Maven
    • LoadBalancer
    • Kotlin Notes
    • Kotlin
    • Kafka
    • jQuery
    • JavaScript
    • Java Notes
    • Java
    • Hystrix
    • Git
    • Gateway
    • Freemarker
    • Feign
    • Eureka
    • ElasticSearch
    • Docker
    • Consul
    • Ajax
    • ActiveMQ
  • 页面
    • 归档
    • 摘要
    • 杂图
    • 问题随笔
  • 友链
    • Spring Cloud Alibaba
    • Spring Cloud Alibaba - 指南
    • Spring Cloud
    • Nacos
    • Docker
    • ElasticSearch
    • Kotlin中文版
    • Kotlin易百
    • KotlinWeb3
    • KotlinNhooo
    • 前端开源搜索
    • Ktorm ORM
    • Ktorm-KSP
    • Ebean ORM
    • Maven
    • 江南一点雨
    • 江南国际站
    • 设计模式
    • 熊猫大佬
    • java学习
    • kotlin函数查询
    • Istio 服务网格
    • istio
    • Ktor 异步 Web 框架
    • PostGis
    • kuangstudy
    • 源码地图
    • it教程吧
    • Arthas-JVM调优
    • Electron
    • bugstack虫洞栈
    • github大佬宝典
    • Sa-Token
    • 前端技术胖
    • bennyhuo-Kt大佬
    • Rickiyang博客
    • 李大辉大佬博客
    • KOIN
    • SQLDelight
    • Exposed-Kt-ORM
    • Javalin—Web 框架
    • http4k—HTTP包
    • 爱威尔大佬
    • 小土豆
    • 小胖哥安全框架
    • 负雪明烛刷题
    • Kotlin-FP-Arrow
    • Lua参考手册
    • 美团文章
    • Java 全栈知识体系
    • 尼恩架构师学习
    • 现代 JavaScript 教程
    • GO相关文档
    • Go学习导航
    • GoCN社区
    • GO极客兔兔-案例
    • 讯飞星火GPT
    • Hollis博客
    • PostgreSQL德哥
    • 优质博客推荐
    • 半兽人大佬
    • 系列教程
    • PostgreSQL文章
    • 云原生资料库
    • 并发博客大佬
Help?

Please contact us on our email for need any support

Support
    首页   ›   Java   ›   正文
Java

Java—集合知识总结

2020-10-26 01:39:22
1341  0 1
参考目录 隐藏
1) 集合概述
2) 集合和数组的区别:
3) Collection接口
4) Collection接口的常用方法
5) Collection子接口之一:List接口
6) (1)List接口的实现类之一:ArrayList
7) (2)List接口的实现类之二:LinkedList
8) (3)List接口的实现类之三:Vector
9) Collection子接口之二:Set接口
10) (1)Set接口的实现类之一:HashSet
11) (2)Set接口的实现类之二:LinkedHashSet
12) (3)Set接口的实现类之三:TreeSet
13) Map接口
14) (1)Map接口的实现类之一:HashMap
15) (2)Map接口的实现类之二:LinkedHashMap
16) (3)Map接口的实现类之三:TreeMap
17) (4)Map接口的实现类之四:Hashtable
18) (5)Map接口的实现类之五:Properties
19) Map的一些使用方式
20) 怎么在java 8的map中使用stream
21) 使用Stream获取map的key
22) 使用stream获取map的value
23) map集合取并集,差集,交集
24) 1.获取两个map的并集
25) 2.获取两个map差集
26) 3.获取连个map交集
27) java8中map新增方法

阅读完需:约 27 分钟

集合概述

集合:集合是Java中提供的一种容器,可以用来存储多个数据。

集合和数组的区别:

(1)数组长度的是固定的,集合的长度是可变的。

(2)数组中存储的都是同一类型的元素。集合存储的都是对象,对象的类型可以不一致。

Java集合类主要由两个根接口Collection和Map派生出来的。Collection有三个子接口: List、Set、Queue(Java5新增的队列)。Java集合大致也可分成List、Set、Queue、Map四种接口体系,注意:Map不是Collection的子接口。 

Map接口:双列数据,保存具有映射关系“key-value对”

Collection接口

Collection接口:单列数据,定义了存取一组对象的方法的集合。

Collection接口是List、Set和Queue接口的父接口,该接口里定义的方法既可用于操作Set集合,也可用于操作List和 Queue集合。

Collection接口的常用方法

Collection子接口之一:List接口

List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。List集合默认按照元素的添加顺序设置元素的索引,可以通过索引(类似数组的下标)来访问指定位置的集合元素。 

List接口的实现类主要有:ArrayList、LinkedList和Vector。

List接口的常用方法

返回值类型  方法名及描述
boolean add(E e) 将指定的元素追加到此列表的末尾(可选操作)。
void add(int index, E element) 将指定的元素插入此列表中的指定位置(可选操作)。
boolean addAll(Collection c) 按指定集合的迭代器(可选操作)返回的顺序将指定集合中的所有元素附加到此列表的末尾。
boolean addAll(int index, Collection c) 将指定集合中的所有元素插入到此列表中的指定位置(可选操作)。
void clear() 从此列表中删除所有元素(可选操作)。
boolean contains(Object o) 如果此列表包含指定的元素,则返回true。
E get(int index) 返回此列表中指定位置的元素。
int hashCode() 返回此列表的哈希码值。
int indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
boolean isEmpty() 如果此列表不包含元素,则返回 true 。
Iterator iterator() 以正确的顺序返回该列表中的元素的迭代器。
int lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
E remove(int index) 删除该列表中指定位置的元素(可选操作)。
E set(int index, E element) 用指定的元素(可选操作)替换此列表中指定位置的元素。
int size() 返回此列表中的元素数。

(1)List接口的实现类之一:ArrayList

ArrayList是List接口的主要实现类,ArrayList是一个动态数组,允许任何符合规则的元素插入包括null。 它能快速随机访问存储的元素,支持随机访问, 查询速度快, 增删元素慢。

ArrayList的JDK1.8之前与之后的实现区别:

JDK1.7:直接创建一个初始容量为10的数组 

JDK1.8:一开始先创建一个长度为0的数组,当添加第一个元素时再创建一个初始容量为10的数组

(2)List接口的实现类之二:LinkedList

LinkedList是List接口的另一个实现,除了可以根据索引访问集合元素外,LinkedList还实现了Deque接口。

LinkedList内部以链表的形式保存集合中的元素,所以随机访问集合中的元素性能较差,但在频繁的插入或删除元素时有较好的性能。

(3)List接口的实现类之三:Vector

Vector大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。

 面试题:

ArrayList和LinkedList的区别

都是线程不安全,相对线程安全的Vector,执行效率高。此外,ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。对于新增和删除操作add(特指插入)和remove,LinkedList比较占优势,因为ArrayList要移动数据。

ArrayList和Vector的区别

Vector和ArrayList几乎是完全相同的,唯一的区别在于Vector是同步类(synchronized),属于强同步类。因此开销就比ArrayList要大,访问要慢。大多数清空下使用 ArrayList而不是Vector,因为同步完全可以由自己来控制。Vector每次扩容请求其大小的2倍空间,而ArrayList是1.5倍。Vector还有一个子类Stack。

Collection子接口之二:Set接口

Set接口也是Collection的子接口,set接口没有提供额外的方法。

Set集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set集合中,则会添加操作失败。

Set集合判断两个对象是否相同是根据 equals() 方法,而不是使用 == 运算符。

(1)Set接口的实现类之一:HashSet

HashSet是Set接口的典型实现,大多数时候使用Set集合时都使用这个实现类。 

HashSet按Hash算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。

HashSet 具有以下特点: 

  • 不能保证元素的排列顺序
  • HashSet不是线程安全的 
  • 集合元素可以是null

HashSet集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。

对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。

HashSet添加元素的原理如下:

当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值,通过某种散列函数决定该对象在HashSet底层数组中的存储位置。

如果两个元素的hashCode()值相等,会再继续调用equals方法,如果equals方法结果为true,则添加失败。如果为false,那么会保存该元素,但是该数组的位置已经有元素了, 那么会通过链表的方式继续链接存储。

如果两个元素的equals() 方法返回true,但它们的 hashCode() 返回值不相等,hashSet将会把它们存储在不同的位置,但依然可以添加成功。

重写hashCode() 方法的基本原则

在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值

当两个对象通过equals()方法比较返回true时,这两个对象的hashCode()方法的返回值应该相等。

对象中用作equals()方法比较的实例变量,都应该用来计算hashCode值。

(2)Set接口的实现类之二:LinkedHashSet

LinkedHashSet是HashSet的子类。

LinkedHashSet也是根据元素的hashCode值来决定元素的存储位置。但它同时使用双向链表维护元素的次序,元素的顺序与添加顺序一致。

由于LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。 

LinkedHashSet不允许集合元素重复。

(3)Set接口的实现类之三:TreeSet

TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。

TreeSet底层使用红黑树结构存储数据元素。

TreeSet两种排序方法:自然排序和定制排序。默认情况下,TreeSet采用自然排序。

自然排序:

TreeSet会调用集合元素的compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。

如果试图把一个对象添加到TreeSet时,则该对象的类必须实现Comparable接口。

实现Comparable的类必须实现compareTo(Object obj) 方法,两个对象即通过compareTo(Object obj) 方法的返回值来比 较大小。

Comparable的一些典型实现类:

  • BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较
  • Character:按字符的 unicode值来进行比较 
  • Boolean:true 对应的包装类实例大于 false 对应的包装类实例 
  • String:按字符串中字符的 unicode 值进行比较 
  • Date、Time:后边的时间、日期比前面的时间、日期大

因为只有相同类的两个实例才会比较大小,所以向TreeSet中添加的应该是同一个类的对象。

对于TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过compareTo(Object obj) 方法比较返回值。

当需要把一个对象放入TreeSet 中,重写该对象对应的equals() 方法时,应保证该方法与compareTo(Object obj) 方法有一致的结果。

对于TreeSet集合而言,它判断两个对象是否相等的标准是:两个对象通过compareTo(Object obj)方法比较是否返回0,如果返回0则相等。

定制排序

TreeSet的自然排序要求元素所属的类实现Comparable接口,如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素,希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法。

利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2。

要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。

使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0。

Map接口

Map与Collection并列存在。用于保存具有映射关系的数据:key-value 

Map中的key和value都可以是任何引用类型的数据 

Map中的key用Set来存放,不允许重复,即同一个Map对象所对应的类,须重写hashCode()和equals()方法

Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和Properties

(1)Map接口的实现类之一:HashMap

HashMap是Map接口使用频率最高的实现类。允许使用null键和null值,与HashSet一样,不保证映射的顺序。 

所有的key构成的集合是Set:无序的、不可重复的。所以,key所在的类要重写:equals()和hashCode()

所有的value构成的集合是Collection:无序的、可以重复的。所以,value所在的类要重写:equals()

HashMap判断两个key相等的标准是:两个key通过equals() 方法返回true, hashCode值也相等。

HashMap判断两个value相等的标准是:两个value通过equals()方法返回true。

HashMap可以使用null值为key或value 

HashMap源码中的重要常量

DEFAULT_INITIAL_CAPACITY: HashMap的默认容量,16 

MAXIMUM_CAPACITY: HashMap的最大支持容量,2^30

TREEIFY_THRESHOLD:Bucket中链表长度大于该默认值,转化为红黑树。

UNTREEIFY_THRESHOLD:Bucket中红黑树存储的Node小于该默认值,转化为链表

table:存储元素的数组,总是2的n次幂

entrySet:存储具体元素的集 

size:HashMap中存储的键值对的数量 

modCount:HashMap扩容和结构改变的次数。

HashMap的存储结构

JDK8之前版本:

JDK8之前HashMap的存储结构是数组+链表结构(即为链地址法) ,当实例化一个HashMap时,系统会创建一个长度为Capacity的Entry数组,这个长度在哈希表中被称为容量 (Capacity),在这个数组中可以存放元素的位置我们称之“桶”(bucket),每个bucket都有自己的索引,系统可以根据索引快速的查找bucket中的元素。

每个bucket中存储一个元素,即一个Entry对象,但每一个Entry对象可以带一个引用变量,用于指向下一个元素,因此,在一个桶中,就有可能生成一个Entry链。 而且新添加的元素作为链表的head。

JDK8之后版本:

JDK8之后HashMap的存储结构是数组+链表+红黑树实现。当实例化一个HashMap时,会初始化initialCapacity和loadFactor,在put第一对映射关系时,系统会创建一个长度为initialCapacity的Node数组,这个长度在哈希表中被称为容量(Capacity),在这个数组中可以存放元素的位置我们称之为 “桶”(bucket),每个bucket都有自己的索引,系统可以根据索引快速的查找bucket中的元素。

每个bucket中存储一个元素,即一个Node对象,但每一个Node对象可以带一个引用变量next,用于指向下一个元素,因此,在一个桶中,就有可能生成一个Node链。也可能是一个一个TreeNode对象,每一个TreeNode对象可以有两个叶子结点left和right,因此,在一个桶中,就有可能生成一个TreeNode树。而新添加的元素作为链表的last,或树的叶子结点。

(2)Map接口的实现类之二:LinkedHashMap

LinkedHashMap 是 HashMap的子类,在HashMap存储结构的基础上,使用了一对双向链表来记录添加元素的顺序。 该链表负责维护Map的迭代顺序,与插入顺序一致,因此性能比HashMap低,但在迭代访问Map里的全部元素时有较好的性能。

(3)Map接口的实现类之三:TreeMap

TreeMap存储Key-Value对时,需要根据key-value对进行排序。TreeMap可以保证所有的Key-Value对处于有序状态。底层采用红黑树的数据结构。

TreeMap也有两种排序方式,自然排序和定制排序。

(4)Map接口的实现类之四:Hashtable

HashMap线程不安全,Hashtable是线程安全的。

HashMap可以使用null值为key或value,Hashtable不允许使用null作为key和value。

Hashtable实现原理和HashMap相同,底层都使用哈希表结构,查询速度快。

Hashtable和HashMap一样也不能保证其中Key-Value对的顺序。

(5)Map接口的实现类之五:Properties

Properties类是Hashtable 的子类,该对象用于处理属性文件。

由于属性文件里的key、value都是字符串类型,所以Properties里的key和value都是字符串类型 。


Map的一些使用方式

怎么在java 8的map中使用stream

Map有key,value还有表示key,value整体的Entry。

创建一个Map:

Map<String, String> someMap = new HashMap<>();

获取Map的entrySet:

Set<Map.Entry<String, String>> entries = someMap.entrySet();

获取map的key:

Set<String> keySet = someMap.keySet();

获取map的value:

Collection<String> values = someMap.values();

上面我们可以看到有这样几个集合:Map,Set,Collection。

除了Map没有stream,其他两个都有stream方法:

所以要将map转化为set或者Collection来操作!!!

Stream<Map.Entry<String, String>> entriesStream = entries.stream();
        Stream<String> valuesStream = values.stream();
        Stream<String> keysStream = keySet.stream();

我们可以通过其他几个stream来遍历map。

使用Stream获取map的key

我们先给map添加几个值:

someMap.put("jack","20");
someMap.put("bill","35");

上面我们添加了name和age字段。

如果我们想查找age=20的key,则可以这样做:

Optional<String> optionalName = someMap.entrySet().stream()
                .filter(e -> "20".equals(e.getValue()))
                .map(Map.Entry::getKey)
                .findFirst();

        log.info(optionalName.get());

因为返回的是Optional,如果值不存在的情况下,我们也可以处理:

optionalName = someMap.entrySet().stream()
                .filter(e -> "Non ages".equals(e.getValue()))
                .map(Map.Entry::getKey).findFirst();

        log.info("{}",optionalName.isPresent());

上面的例子我们通过调用isPresent来判断age是否存在。

如果有多个值,我们可以这样写:

someMap.put("alice","20");
        List<String> listnames = someMap.entrySet().stream()
                .filter(e -> e.getValue().equals("20"))
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

        log.info("{}",listnames);

上面我们调用了collect(Collectors.toList())将值转成了List。

使用stream获取map的value

上面我们获取的map的key,同样的我们也可以获取map的value:

List<String> listAges = someMap.entrySet().stream()
                .filter(e -> e.getKey().equals("alice"))
                .map(Map.Entry::getValue)
                .collect(Collectors.toList());

        log.info("{}",listAges);

上面我们匹配了key值是alice的value。


map集合取并集,差集,交集

1.获取两个map的并集

/**

取Map集合的并集
@param map1 大集合
@param map2 小集合
@return 两个集合的并集
*/
public static Map<String, Object> getUnionSetByGuava(Map<String, Object> map1, Map<String, Object> map2) {
//获取map的key
Set bigMapKey = map1.keySet();
Set smallMapKey = map2.keySet();
//Sets.union--union()方法返回两个集合的并集,包含所有集合的元素,重复元素只会出现一次。
Set differenceSet = Sets.union(bigMapKey, smallMapKey);
Map<String, Object> result = Maps.newHashMap();
for (String key : differenceSet) {
//map1.containsKey(key) -- 用来验证是否存在此KEY值,KEY值必须是全符合,包含也是失败返回false。
if (map1.containsKey(key)) {
result.put(key, map1.get(key));
} else {
result.put(key, map2.get(key));
}
}
return result;
}

set.union() 返回两个集合的并集

union()方法返回两个集合的并集,包含所有集合的元素,重复元素只会出现一次。
语法:
  set.union(set1,set2)
参数:
  set1必填参数,合并的目标集合
  set2选填参数,其他要合并的集合,多个集合之间用逗号隔开。

返回值:
  返回一个新的集合。

MAP使用containsKey和containsValue方法,验证键值对是否存在此KEY或VAL值。

containsKey

containsKey
boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true。更确切地讲,当且仅当此映射包含针对满足 (key==null ? k==null : key.equals(k)) 的键 k 的映射关系时,返回 true。(最多只能有一个这样的映射关系)。 

参数:
key - 测试是否存在于此映射中的键 
返回:
如果此映射包含指定键的映射关系,则返回 true 
抛出: 
ClassCastException - 如果该键对于此映射是不合适的类型(可选) 
NullPointerException - 如果指定键为 null 并且此映射不允许 null 键(可选)

用来验证是否存在此KEY值,KEY值必须是全符合,包含也是失败返回false。

例子:

package demo;
 
import java.util.HashMap;
import java.util.Map;
 
public class fordemo
{
public static void main(String[] args)
{
Map<String, String> paramMap=new HashMap<String, String>();
	paramMap.put("bc", "aa");
	paramMap.put("a", "bb");
	System.out.println(paramMap.containsKey("b"));--返回false
	System.out.println(paramMap.containsKey("a"));--返回true
}
}

containsValue

containsValue
boolean containsValue(Object value)如果此映射将一个或多个键映射到指定值,则返回 true。更确切地讲,当且仅当此映射至少包含一个对满足 (value==null ? v==null : value.equals(v)) 的值 v 的映射关系时,返回 true。对于大多数 Map 接口的实现而言,此操作需要的时间可能与映射大小呈线性关系。 
 
参数:
value - 测试是否存在于此映射中的值 
返回:
如果此映射将一个或多个键映射到指定值,则返回 true 
抛出: 
ClassCastException - 如果该值对于此映射是不合适的类型(可选) 
NullPointerException - 如果指定值为 null 并且此映射不允许 null 值(可选)

用来验证是否存在此Value值,Value值必须全部符合,包含也是返回false。

例子:

package demo;
 
import java.util.HashMap;
import java.util.Map;
 
public class fordemo
{
public static void main(String[] args)
{
Map<String, String> paramMap=new HashMap<String, String>();
	paramMap.put("1", "b");
	paramMap.put("2", "b");
	paramMap.put("3", "ab");
	paramMap.put("4", "cc");
	System.out.println(paramMap.containsValue("b"));--返回true
	System.out.println(paramMap.containsValue("a"));--返回false
	System.out.println(paramMap.containsValue("cc"));--返回true
}
}

2.获取两个map差集

/**

取Map集合的差集
@param bigMap 大集合
@param smallMap 小集合
@return 两个集合的差集
*/
public static Map<String, Object> getDifferenceSetByGuava(Map<String, Object> bigMap, Map<String, Object> smallMap) {
Set bigMapKey = bigMap.keySet();
Set smallMapKey = smallMap.keySet();
//difference -- difference()函数用户返回两个集合的差集,即返回的在第一个集合但不在第二个集合中的元素
Set differenceSet = Sets.difference(bigMapKey, smallMapKey);
Map<String, Object> result = Maps.newHashMap();
for (String key : differenceSet) {
result.put(key, bigMap.get(key));
}
return result;
}

difference:

描述:

difference()函数用户返回两个集合的差集,即返回的在第一个集合但不在第二个集合中的元素

语法:

set1.difference(set2)

实例:

x={'a','b','c'}
y={'a','d','e'}
print(x.difference(y))
 
#输出
{'b', 'c'}

3.获取连个map交集

/**

取Map集合的交集(String,String)
@param map1 大集合
@param map2 小集合
@return 两个集合的交集
*/
public static Map<String, Object> getIntersectionSetByGuava(Map<String, Object> map1, Map<String, Object> map2) {
Set bigMapKey = map1.keySet();
Set smallMapKey = map2.keySet();
Set differenceSet = Sets.intersection(bigMapKey, smallMapKey);
Map<String, Object> result = Maps.newHashMap();
for (String key : differenceSet) {
result.put(key, map1.get(key));
}
return result;
}

intersection:

描述:

intersection()方法用于返回两个或更多集合中都包含的元素,即交集。

语法:

set.intersection(set1,set2,...)

参数:

  • set1–必需,要查找相同元素的集合
  • set2–可选,其他要查找相同元素的集合,可以多个,多个逗号隔开

返回值:

  • 返回一个新的集合

实例:

x={'a','b','c'}
y={'a','d','e'}
print(set.intersection(x,y))
 
#输出
{'a'}


java8中map新增方法

getOrDefault

如果Map中不存在该key,可以提供一个默认值,方法会返回改默认值。如果存在该key,返回键对应的值。

java8之前的写法:

Map<String, String> map = new HashMap<>();
String value = "D";
if(map.containsKey("d")) {
	value = map.get("d");
}

java8:
String value = map.getOrDefault("d", "D");

forEach

forEach遍历map,对map中的每个映射执行action指定的操作

Map<String, String> map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");

// 遍历
map.forEach((k, v)-> {
	System.out.println(k + "=" + v);
	map.put(k, k + v);
});
// 输出
// a=A
// b=B

map.forEach((k, v)-> {
	System.out.println(k + "=" + v);
});
// 输出
// a=aA
// b=bB

putIfAbsent

putIfAbsent(K key, V value)只有在不存在key值的映射或者映射值为null,才将value值赋值给key。否则不做修改。该方法将条件判断和赋值合二为一。

Map<String, String> map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");
        
String e = map.putIfAbsent("e", "E");
String b = map.putIfAbsent("b", "E");
System.out.println("返回e="+e); //返回e=null
System.out.println("键e="+map.get("e"));//键e=E
System.out.println("返回b="+b);//返回b=B
System.out.println("键b="+map.get("b"));//键b=B

remove

只有在当前Map中key映射的值等于value时才删除该映射,否则什么也不做。

Map<String, String> map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");

map.remove("a", "B");
map.remove("b", "B");
System.out.println(map.get("a")); // A
System.out.println(map.get("b")); // null

replace(K key, V value)

只有在当前Map中包含key,才用value去替换原来的值,否则什么也不做。

Map<String, String> map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");

map.replace("c", "1");
map.replace("b", "1");
System.out.println(map.get("c")); // null
System.out.println(map.get("b")); // 1

replace(K key, V oldValue, V newValue)

只有在当前Map中key的映射存在且映射的值等于oldValue时才用newValue去替换原来的值,否则什么也不做。

Map<String, String> map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");

map.replace("a", "1", "2");
map.replace("b", "B", "2");
System.out.println(map.get("a")); // A
System.out.println(map.get("b")); // 2

replaceAll

作用是对Map中的每个映射执行function指定的操作,并用function的执行结果替换原来的value

Map<String, String> map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");

map.replaceAll((k, v) -> v.toLowerCase());
map.forEach((k, v)-> {
	System.out.println(k + "=" + v);
});

// a=a
// b=b

merge

如果Map中key对应的映射不存在或者为null,则将value关联到key上;否则执行remappingFunction,如果执行结果为null则删除key的映射,否则用该结果跟key关联。

Map<String, String> map = new HashMap<>();
map.put("e", "E");
map.merge("f", "F", String::concat);
map.merge("e", "F", String::concat);
System.out.println("map.get(\"f\")="+map.get("f")); // map.get("f")=F
System.out.println("map.get(\"e\")="+map.get("e")); // map.get("e")=EF
		

compute

Map<String, String> map = new HashMap<>();
map.put("b", "B");
String val = map.compute("b", (k, v) -> null); 
String val2 = map.compute("c", (k, v) -> v + "+v");
System.out.println(val); // null
System.out.println(val2); // null+v

computeIfAbsent

当Map中不存在key值的映射或映射值为null时,调用mappingFunction,并在mappingFunction执行结果非null时,将结果赋值给key。

List<String> list = Lists.newArrayList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g");
Map<String, List<Integer>> positionsMap = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
    positionsMap.computeIfAbsent(list.get(i), k -> Lists.newArrayListWithCapacity(1)).add(i);
}

System.out.println(positionsMap);
// {a=[0], b=[1, 2], c=[3, 4, 5], d=[6, 7, 8], f=[9, 10], g=[11]}

如本文“对您有用”,欢迎随意打赏作者,让我们坚持创作!

1 打赏
Enamiĝu al vi
不要为明天忧虑.因为明天自有明天的忧虑.一天的难处一天当就够了。
543文章 68评论 294点赞 594550浏览

随机文章
ElasticSearch—安装(二)
5年前
Java—I/O模型与同步、异步、阻塞、非阻塞
3年前
SpringSecurity—AuthenticationManagerBuilder (认证管理器分析)
5年前
SpringBoot—AOP的用法
5年前
Spring—IOC容器(构建)
3年前
博客统计
  • 日志总数:543 篇
  • 评论数目:68 条
  • 建站日期:2020-03-06
  • 运行天数:1927 天
  • 标签总数:23 个
  • 最后更新:2024-12-20
Copyright © 2025 网站备案号: 浙ICP备20017730号 身体没有灵魂是死的,信心没有行为也是死的。
主页
页面
  • 归档
  • 摘要
  • 杂图
  • 问题随笔
博主
Enamiĝu al vi
Enamiĝu al vi 管理员
To be, or not to be
543 文章 68 评论 594550 浏览
测试
测试
看板娘
赞赏作者

请通过微信、支付宝 APP 扫一扫

感谢您对作者的支持!

 支付宝 微信支付