[英]Optional.map - how does it work exactly?
我試圖研究Java 8中的Optional問題。我編寫了一個非常簡單的程序,該程序由一個類和main()
方法組成。
我希望輸出數據為[aaa, DDD, ccc]
。 但是,我得到了[aaa, bbb, ccc]
。 但是,如果將s = new TestClass("DDD")
行更改為已注釋的行,我將得到所需的內容。
那么map()
如何工作? 是否可以僅通過編輯來映射對象? 如果創建一個新實例並返回它,為什么它不能正常工作?
類:
public class TestClass {
String str;
public TestClass(String str) {
this.str = str;
}
@Override
public String toString() {
return str;
}
}
main()方法:
public static void main(String[] args) {
List<TestClass> list = new ArrayList<TestClass>();
list.add( new TestClass("aaa") );
list.add( new TestClass("bbb") );
list.add( new TestClass("ccc") );
list.stream()
.filter( s -> s.str.equals("ccc") || s.str.equals("bbb") )
.findFirst()
.map( s -> {
// s.str = "DDD"; this works just fine
s = new TestClass("DDD");
return s;
} );
System.out.println(list);
}
隨着s.str = "DDD"
要修改或突變的TestClass
列表中設置它的實例str
領域重視DDD
。
使用s = new TestClass("DDD")
,您不會觸摸列表中的實例。 變量s
是該lambda塊的局部變量。 給它分配一個新的對象引用不會更改它先前指向的對象的str
字段。
通常,使用地圖,您必須將其收集起來或對結果進行某些處理。 但是在這里您不對映射結果做任何事情。
請將您的代碼更改為:
Optional<Object> result = list.stream()
.filter( s -> s.str.equals("ccc") || s.str.equals("bbb") )
.findFirst()
.map( s -> {
// s.str = "DDD"; this works just fine
s = new TestClass("DDD");
return s;
} );
System.out.println(result);
然后再次運行-它應該會給您一些提示。
請注意,您根本不會在版本中使用結果,在這種情況下修改源列表不是最佳習慣(可能存在多線程問題)
您正在分配方法中的一個新的對象。
您的新引用僅在方法范圍內有效,但是一旦返回,該引用將指向其原始實例。
在java
這是預期的行為。
例如:
String s = "foo";
changeString(s);
print(s); // prints "foo"
哪里
void changeString(String s) {
s = "bar";
}
但是,沒有s.str = "DDD"
您使用s.str = "DDD"
那樣禁止您更改對象屬性(當然,除非您的對象是不可變的)。
在您的特定情況下,您對map
lambda結果不做任何事情,因此您所做的更改會丟失。
實際上,即使您只是執行s.str = "DDD"
, map
對於您來說還是沒有用的,因為它可以在forEach
完成。
但是 。 由於您只處理一個結果,甚至可能不存在(可選),因此應使用
...findFirst().ifPresent(s -> s.str = "DDD" );
僅當需要將對象轉換為其他類型以進行進一步處理時,才應使用map
。
'map'方法用於將每個元素映射到其相應的結果。 如果要更改列表的一個元素,則需要將結果收集到新列表中。 使用.collect()方法。
List<TestClass> list = new ArrayList<TestClass>();
list.add( new TestClass("aaa") );
list.add( new TestClass("bbb") );
list.add( new TestClass("ccc") );
List<TestClass> result = list.stream()
.map( s -> {
if (s.toString().equals("bbb")) {
s = new TestClass("DDD");
}
return s;
}).collect(Collectors.toList());
for(TestClass t : result){
System.out.println(t);
}
結果是:
aa
DDD
抄送
整理流:
List<TestClass> result = list.stream()
.map( s -> s.toString().equals("bbb") ? new TestClass("DDD") : s)
.collect(Collectors.toList());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.