成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

可以向ToList()返回的集合Add元素嗎?

開發(fā) 前端
架構如果Spring家族沒有推出Spring Boot,Spring是有被取代風險的,因為那時的開發(fā)者對它的配置繁瑣、使用曲線較高已有所反感(即使比EJB還輕太多)。

??前言

讀過《Java核心技術》的同學可能記得里面有一句話:“注意不要編寫返回引用可變對象的訪問器方法”。對于這句話,筆者在和同事交流常表示:若你遇見有同事代碼能這么寫的,一定值得你的高看(雖不一定有實際作用),因為這就是coding sense,相對稀有。

本文討論的議題是:Stream流返回集合時,是否可以繼續(xù)向此集合add元素?

?正文

Java 8的Stream流有兩大特點:

  • 不可變:不影響原集合,每次調用都返回一個新的Stream
  • 延遲執(zhí)行:在遇到終結操作之前,Stream不會執(zhí)行

這里面有個“不可變”,針對于這里它有兩重含義:

  1. 每次操作都會生成一個新的Stream。因此Stream是不可變的(就像LocalDate、String等)
  2. 原集合不受影響。在進行數據操作時,不會對原來的集合元素有影響

總之,在使用Stream時,我們不用關心操作對原集合帶來的“副作用”,非常省心。

toList()/toSet()返回的集合類型

Stream操作最常用的莫過于toList()和toSet()兩個Collector收集方式,看看返回的是什么類型勒。

toList()

@Test
public void fun() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);

List<Integer> streamResultForList = list.stream().collect(toList());
System.out.println("toList()返回的類型:" + streamResultForList.getClass());
System.out.println(streamResultForList.getClass() == list.getClass());
}

運行程序,輸出:

toList()返回的類型:class java.util.ArrayList
true

toSet()

@Test
public void fun1() {
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);

Set<Integer> streamResultForSet = set.stream().collect(toSet());
System.out.println("toSet()返回的類型:" + streamResultForSet.getClass());
System.out.println(streamResultForSet.getClass() == set.getClass());
}

運行程序,輸出:

toSet()返回的類型:class java.util.HashSet
true

結論:

  • toList()返回的是ArrayList類型
  • toSet()返回的是HashSet類型

原理

已經知道了返回類型,就順勢再走近一點,看看為啥返回的是這個結果呢?

其實僅僅只需向前一小步,點進去源碼一看便知:

圖片

圖片

標題問題的答案

可以。不管是toList()還是toSet()返回的都是咱最常用的集合類型,所以肯定可以add元素呀。

@Test
public void fun2() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);

System.out.println(list.getClass());

List<Integer> streamResultForList = list.stream().collect(toList());
streamResultForList.add(10);
System.out.println("stream后的集合:" + streamResultForList);
System.out.println("源集合:" + list);
}

運行程序,輸出:

class java.util.ArrayList
stream后的集合:[1, 2, 3, 10]
源集合:[1, 2, 3]

stream后的集合成功添加了元素10,但源集合不受影響哦。

如何返回不可變集合

返回不可變引用(對象、集合)是提高程序健壯性的有效手段之一,那么如何做到返回一個不可變(或者線程安全)的集合呢?

其實,上面的截圖里,JDK已經給了我們答案:

圖片

簡而言之:如果希望返回自己控制的結合類型,請使用toCollection(Supplier)收集器,具體返回什么樣的集合,交給使用者實現Supplier。

這里,筆者通過三種方式用三種方式來返回不可變集合類型,供你參考:

方式一:直接提供一個不可變集合的實例

@Test
public void fun4() {
List<Integer> list = new ArrayList<>();

Collection<Integer> streamCollection = list.stream().collect(toCollection(()-> Arrays.asList()));
System.out.println("stream后的集合類型:" + streamCollection.getClass());
streamCollection.add(10);
}

運行結果:
stream后的集合類型:class java.util.Arrays$ArrayList
java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)

方式二:間接提供一個不可變集合的實例

@Test
public void fun5() {
List<Integer> list = new ArrayList<>();

Collection<Integer> streamCollection = list.stream().collect(toCollection(() -> Collections.unmodifiableList(new ArrayList<>())));
System.out.println("stream后的集合類型:" + streamCollection.getClass());
streamCollection.add(10);
}

運行結果:
stream后的集合類型:class java.util.Collections$UnmodifiableRandomAccessList
java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Collections.java:1057)

方式三:使用collectingAndThen分布進行(推薦)

@Test
public void fun6() {
List<Integer> list = new ArrayList<>();

Collection<Integer> streamCollection = list.stream()
.collect(collectingAndThen(toSet(), l -> Collections.unmodifiableSet(l)));
System.out.println("stream后的集合類型:" + streamCollection.getClass());
streamCollection.add(10);
}

運行結果:
stream后的集合類型:class java.util.Collections$UnmodifiableSet
java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Collections.java:1057)

給你留哥問題:返回線程安全的集合類型,你會了嗎?

??總結

本文除了弄清楚標題所描述的問題外,另一目的是建議coder們都能有引用類型“不可變”的意識(當然后面有專文分享這個話題),代碼水平或許就是這樣一步步提升的,積跬步方可至千里。

本專欄源代碼庫:https://github.com/yourbatman/yourbatman-999-question

  • 個人博客:https://yourbatman.cn
  • 程序員網盤:https://wangpan.yourbatman.cn
  • 女媧工程:https://start.yourbatman.cn
  • 更多專欄:??https://yourbatman.cn/columns?? |或| 公號后臺回復“專欄列表”獲取全部小而美的原創(chuàng)技術專欄

我是YourBatman,一個俗人,貪財好色。歷經過延期畢業(yè)、賣保險、送外賣的大齡程序員,《夢幻西游》骨灰玩家;龍珠迷、火影迷。現資深領域建模專家、Java架構師;高質量代碼、DDD面向對象設計布道師;Spring開源貢獻者,CSDN博客之星年度Top 10,出版書籍《Spring奇淫巧技》&《領域建模之面向對象程序設計》進行時。

責任編輯:武曉燕 來源: YourBatman
相關推薦

2023-03-04 21:05:53

JAVA泛型通配符

2023-11-07 07:39:56

Java集合數據結構

2010-04-14 15:09:49

Oracle函數

2023-08-13 16:17:31

2022-01-07 19:50:14

元素java集合

2009-12-22 16:50:44

ADO.NET元素

2009-12-21 15:33:07

WCF集合元素

2009-11-19 17:04:30

動態(tài)路由技術

2011-08-12 11:04:47

Oracle數據庫增刪集合元素Java

2023-11-17 18:01:48

CIOCTO

2012-03-19 09:57:09

JavaArrayList

2011-05-12 18:21:42

C++

2020-08-06 07:49:57

List元素集合

2022-12-14 09:10:06

JAVA注解繼承

2019-03-04 09:22:52

阿里巴巴foreach Java

2024-10-09 08:42:03

2023-12-01 11:13:50

JavaTreeSet

2019-07-24 15:33:55

大數據數據處理分析

2023-02-27 07:56:55

IngressKubernetes

2025-01-20 13:00:00

GPTSpringJava
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品一区二区三区不卡 | 91亚洲欧美 | 亚洲男女激情 | 久久精品视频在线播放 | 最新av片| 中文字幕乱码一区二区三区 | 亚洲一区在线日韩在线深爱 | 99久视频 | 免费久久99精品国产婷婷六月 | 操亚洲| 亚洲免费久久久 | 国产超碰人人爽人人做人人爱 | 久久人| 日日日色 | 亚洲黄色一级毛片 | 欧美精品电影一区 | 在线看国产 | 麻豆精品国产91久久久久久 | 91免费版在线观看 | 色综合久久天天综合网 | 国产美女在线播放 | 国产精品视频在线免费观看 | 国产人成精品一区二区三 | 亚洲精品一区二区三区中文字幕 | 久久国产精品偷 | 性一爱一乱一交一视频 | 日韩精品视频在线播放 | 国产高清视频在线观看 | 在线观看成人 | 中文字幕亚洲欧美 | 欧美aⅴ片 | 性色网站 | av官网在线| 国产成人亚洲精品 | 国产在线资源 | 亚洲精品一区二区网址 | 99福利| 一区二区成人在线 | 日韩在线看片 | 成人亚洲精品 | 欧美激情视频一区二区三区在线播放 |