亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 8 中不干涉的例子

Java 8 中不干涉的例子

慕容森 2021-08-13 16:45:10
根據這個問題,我們可以修改源,它不稱為干擾:您可以修改流元素本身,不應將其稱為“干擾”。根據這個問題,代碼List<String> list = new ArrayList<>();  list.add("test");  list.forEach(x -> list.add(x));會扔ConcurrentModificationException。但我的代碼,Employee[] arrayOfEmps = {                new Employee(1, "Jeff Bezos"),                new Employee(2, "Bill Gates"),                new Employee(3, "hendry cavilg"),                new Employee(4, "mark cuban"),                new Employee(5, "zoe"),                new Employee(6, "billl clinton"),                new Employee(7, "ariana") ,                new Employee(8, "cathre"),                new Employee(9, "hostile"),                new Employee(10, "verner"),            };        Employee el=new Employee(1, "Jeff Bezos");        List<Employee> li=Arrays.asList(arrayOfEmps);        li.stream().map(s->{s.setName("newname");return s;}).forEach(System.out::print);不會 throw ConcurrentModificationException,即使它實際上改變了源。而這段代碼,Employee[] arrayOfEmps = {                new Employee(1, "Jeff Bezos"),                new Employee(2, "Bill Gates"),                new Employee(3, "hendry cavilg"),                new Employee(4, "mark cuban"),                new Employee(5, "zoe"),                new Employee(6, "billl clinton"),                new Employee(7, "ariana") ,                new Employee(8, "cathre"),                new Employee(9, "hostile"),                new Employee(10, "verner"),            };        Employee el=new Employee(1, "Jeff Bezos");        List<Employee> li=Arrays.asList(arrayOfEmps);        li.stream().map(s->{s.setName("newname");li.add(s);return s;}).limit(10).forEach(System.out::print);因此,我不完全了解允許對源進行哪些類型的修改,哪些不允許??吹揭粋€干擾并產生有狀態和副作用的流的示例會非常有幫助,并正確指示哪個是哪個。
查看完整描述

3 回答

?
holdtom

TA貢獻1805條經驗 獲得超10個贊

當你這樣做時:


li.stream().map(s->{s.setName("newname");return s;})


您沒有更改列表本身,而是更改了此列表中的一個元素;所以它不會ConcurrentModificationException像你預期的那樣觸發 a 。


在最后一個代碼片段中,您使用的是Array.asList.

您必須知道在數組(一個特定的內部 ArrayList類)上Array.asList返回一個只讀包裝器,解釋為什么不支持。 add


事實上,這個內部類并沒有在設計上覆蓋AbstractList#add方法;造成UnsupportedOperationException; 仍然不像ConcurrentModificationException你預期的那樣。


這是一個類似于您的最后一個片段的示例,它確實拋出了一個ConcurrentModificationException:


public static void main(String[] args) {

    Employee[] arrayOfEmps = {

      new Employee(1, "Jeff Bezos")

    };

    Employee el = new Employee(11, "Bill Gates");

    List<Employee> li = new ArrayList<>(Arrays.asList(arrayOfEmps)); // to avoid read-only restriction

    li.stream().peek(s -> li.add(el)).forEach(System.out::print);

請注意,我Arrays.List用 "true"包裝返回ArrayList,允許寫入,因為它實現了該add方法;)


查看完整回答
反對 回復 2021-08-13
?
陪伴而非守候

TA貢獻1757條經驗 獲得超8個贊

您的第一個示例更改 的現有元素Stream,但不會從源中添加或刪除元素。因此,這不是干擾。


您的第二個示例嘗試通過在Stream管道期間向源添加元素來進行干擾。但是,您得到了UnsupportedOperationException而不是ConcurrentModificationException,因為您嘗試將元素添加到固定大小List(由 返回Arrays.asList)。


將您的第二個示例更改為:


List<Employee> li=new ArrayList<>(Arrays.asList(arrayOfEmps));

li.stream().map(s->{s.setName("newname");li.add(s);return s;}).limit(10).forEach(System.out::print);

你應該得到ConcurrentModificationException.


查看完整回答
反對 回復 2021-08-13
?
慕尼黑5688855

TA貢獻1848條經驗 獲得超2個贊

這稱為 . 來源的結構性對非結構性變化Stream。例如ArrayListdoc 說:


僅僅設置元素的值不是結構修改......


因此,在您的示例中,這意味著更改Employee本身不會更改List本身(不會刪除或添加元素)。但是改變List本身,將失敗ConcurrentModificationException:


List<Integer> list = new ArrayList<>();

list.add(1);

list.add(2);


list.stream().forEach(x -> list.remove(x));

但是有些來源的干擾不僅僅是可以的,稱為弱一致遍歷,例如ConcurrentHashMap:


 ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<>();

 chm.put(1, "one");

 chm.put(2, "two");

 chm.put(3, "three");


 chm.entrySet().stream()

         .forEach(x -> chm.remove(x.getKey()));

這不會失敗ConcurrentModificationException。


查看完整回答
反對 回復 2021-08-13
  • 3 回答
  • 0 關注
  • 233 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號