[英]Java 8 stream with two Lists
我有一個方法需要2個列表作為參數,你可以在方法體中看到我想做一些過濾並將結果返回給調用者。 我想用lambda表達式將此代碼轉換為Java 8流,但我無法弄清楚。 我最終為此創建了多個流,它擊敗了這個重構(恕我直言)的目的。 我想知道的是,我如何以簡單的方式將其重構為一個流?
public Set<CustomerTrack> getCustomerTracks(List<CusomerTrack> tracks, List<Customer> customers) {
Set<CustomerTrack> tracksToSave = new HashSet<>();
for (Customer customer : customers) {
if (customer.getTrack() == null) {
continue;
}
Long allowedTrackId = customer.getTrack().getId();
for (CustomerTrack track : tracks) {
if (Long.valueOf(track.getId()).equals(allowedTrackId)) {
tracksToSave.add(track);
}
}
}
return tracksToSave;
}
似乎這就是你所追求的:
customers.stream()
.filter(c -> c.getTrack() != null)
.map(c -> c.getTrack().getId())
.flatMap(id -> tracks.stream().filter(track -> Long.valueOf(track.getId()).equals(id)))
.collect(Collectors.toSet());
請注意,對於每個id
您將迭代整個tracks
列表; 這具有O(n*m)
復雜度。 這通常被認為是壞的,你可以改善它。
為了使它更好,你首先要從Customer
創建一個HashSet
的ID; 擁有該HashSet
你現在可以使用你感興趣的id調用contains
,因為contains
的時間復雜度為O(1)
(它實際上稱為O(1)
攤銷復雜度)。 所以現在你的復雜性變成了O(n)
+ O(1)
,但是因為O(1)
是一個常數,它實際上是O(n)
- 比你以前的更好。 在代碼中:
Set<Long> set = customers.stream()
.filter(c -> c.getTrack() != null)
.map(c -> c.getTrack().getId())
.collect(Collectors.toSet());
Set<CusomerTrack> tracksToSave = tracks.stream()
.filter(track -> set.contains(track.getId())
.collect(Collectors.toSet()));
首先,您可以創建一組允許的ID:
Set<Long> collect = customers.stream()
.filter(customer -> customer.getTrack() != null)
.map(customer -> customer.getTrack().getId())
.collect(Collectors.toSet());
然后你可以填充你的曲目集
Set<CusomerTrack> tracksToSave = tracks.stream()
.filter(track -> collect.contains(Long.valueOf(track.getId())))
.collect(Collectors.toSet());
另一種有利於方法引用的方法:
Set<Track> tracks =
customers.stream()
.map(Customer::getTrack) // customer to track
.filter(Objects::nonNull) // keep non null track
.map(Track::getId) // track to trackId
.flatMap(trackId -> tracks.stream() // collect tracks matching with trackId
.filter(t-> Long.valueOf(t.getId()).equals(trackId))
)
.collect(toSet());
你可以嘗試這樣的事情
customers
.stream()
.map(Customer::getTrack)
.filter(Objects::nonNull)
.map(CustomerTrack::getId)
.flatMap(trackId -> tracks
.stream()
.filter(track -> Long.valueOf(track.getId()).equals(trackId)))
.collect(Collectors.toSet());
這里重要的運算符是flatMap
Set<CustomerTrack> tracksToSave = customers.stream()
.map(Customer::getTrack)
.filter(track -> track != null)
.flatMap(track -> {
tracks.stream.filter(it -> Long.valueOf(it.getId()).equals(track.getId())))
.collect(Collectors.toSet());
試試這個吧
customers.stream()
.filter(customer -> customer.getTrack() != null)
.map(c -> c.getTrack().getId())
.forEach(allowedTrackId -> {
tracks.stream()
.filter(track -> Long.valueOf(track.getId()).equals(allowedTrackId))
.forEach(tracksToSave::add);
});
您需要先過濾空值,然后使用customerTrack列表對其進行過濾。
希望這個答案可以幫到你。
return customers.stream().map(cust-> cust.track).filter(track -> track != null).
collect(Collectors.toList())
.stream().filter(track-> customerTracks.stream()
.anyMatch(ele -> ele.getId() ==
track.getId())).collect(Collectors.toSet());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.