[英]How to filter element from a List using Java 8 streams?
我有一個使用filter()
操作的簡單 Java 8 示例。
當我嘗試過濾時,我得到一個空列表。
class Per {
String id;
Per(String id) {
this.id = id;
}
public String getId() {
return id;
}
public static void main(String[] args) {
List<String> allIds = new ArrayList<>();
allIds.add("1");
allIds.add("2");
allIds.add("3");
allIds.add("4");
List<Per> unavailableItems = new ArrayList<>();
unavailableItems.add(new Per("2"));
unavailableItems.add(new Per("4"));
List<Per> ids = unavailableItems.stream().filter(per -> !(allIds.contains(per.getId())))
.collect(Collectors.toList());
System.out.println(ids);// why its returning empty value
}
}
為什么得到一個空列表?
您將得到一個空列表,因為操作filter()
將僅在 stream 中保留與給定謂詞匹配的元素。
返回一個 stream,該 stream 的元素與給定的謂詞相匹配。
由於源列表中的所有值都存在於allIds
列表中,因此謂詞始終返回false
。
如果只想保留allIds
列表中存在的元素,請將謂詞更改為:
filter(per -> allIds.contains(per.getId()))
為了降低contains()
檢查的時間復雜度,您還可以將allIds
設為HashSet
。
如果你想做相反的檢查——找到可用id
的列表(來自allIds
列表的id
不存在於unavailableItems
中)你可以這樣做:
List<String> availableId = allIds.stream()
.filter(id -> unavailableItems.stream()
.noneMatch(pers -> pers.getId() == id))
.collect(Collectors.toList());
如果這就是您想要實現的目標,我的建議是通過生成一個Map<String, Per>
- person by id基於availableId
列表來改進上面的代碼。 並檢查id
是否不存在於 map 中,而不是遍歷整個availableId
列表。
Map<String, Per> personById = unavailableItems.stream()
.collect(Collectors.toMap(Per::getId, Function.identity()));
List<String> availableId = allIds.stream()
.filter(id -> !personById.containsKey(id))
.collect(Collectors.toList());
你的過濾條件前面有一個 not 標志:
!(allIds.contains(per.getId()))
因此,您不是過濾列表內的項目,而是過濾不在列表內的項目。 您 unavailibleItems 列表僅包含在 allIds 列表中具有匹配項目的項目,這意味着這種情況永遠不會成立。 但是,如果您刪除了非符號,它會起作用,或者如果您將項目添加到 unavailibleItems 列表中,但在 allId 的列表中沒有匹配值,它會起作用。
讀取filter
為:
“我應該包括(過濾)這個項目,是或否”
因此,當您的代碼執行以下操作時:
List<Per> ids = unavailableItems.stream().filter(per -> !(allIds.contains(per.getId())))
然后你的代碼檢查它是否應該刪除項目Per("2")
邏輯是“如果allIds
有一個"2"
?那么不,不過濾它,不包括它(那是!
在你的代碼中)
事實上,你沒有包括它。
然后用Per("4")
重復,你也不包括它。
不包括這兩個元素的結果是一個空列表。
我希望這有助於澄清它。
您可能認為“過濾”的意思是“過濾掉”或“排除”,但恰恰相反。
在我看來,您正在嘗試做相反的事情,從allIds
中過濾那些在unavailableItems
中的元素
在這種情況下:
List<String> allAvailable = allIds.stream().filter( id -> {
for (Per p : unavailableItems) {
if ( p.getId().equals(id)) {
return false;
}
}
return true;
}).collect(Collectors.toList());
System.out.println(allAvailable);
完全按照您的需要進行打印:
[1, 3]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.