4 回答

TA貢獻(xiàn)1777條經(jīng)驗(yàn) 獲得超3個(gè)贊
你可以這樣嘗試:
Map<TimeStamp, Optional<Obj>> result =
list.stream().collect(Collectors.groupingBy(
Obj::getTs,
Collectors.maxBy(Comparator.comparing(Obj::getGenerationTs))
));
正如@Naman 在評(píng)論中所說(shuō)的更完整的選項(xiàng):
list.stream().collect(Collectors.groupingBy(
Obj::getTs,
Collectors.maxBy(Comparator.comparing(Obj::getGenerationTs))
)).values().stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超5個(gè)贊
您當(dāng)然可以Stream使用地圖收集器然后獲取值來(lái)做到這一點(diǎn)
Collection<Obj> objects = list.stream()
.collect(Collectors.toMap(Obj::getTimeStamp,
Function.identity(),
(o1, o2) -> o1.getGenerationTs().isBefore(o2.getGenerationTs()) ? o2 : o1))
.values();
List<Obj> listOfObjects = new ArrayList<>(objects);
甚至更短:
List<Obj> result = list.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(Obj::getTimeStamp,
Function.identity(),
(o1, o2) -> o1.getGenerationTs().isBefore(o2.getGenerationTs()) ? o2 : o1),
m -> new ArrayList<>(m.values())));

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超6個(gè)贊
如果您已經(jīng)有一個(gè)排序列表(按 降序generationTs),就像您在示例代碼中那樣,您可以使用 aHashSet和Collection.removeIf()從該列表中刪除所有重復(fù)的時(shí)間戳:
list.sort(Comparator.comparing(Obj::getTs)
.thenComparing(Comparator.comparing(Obj::getGenerationTs)
.reversed()));
Set<Timestamp> keys = new HashSet<>();
list.removeIf(o -> !keys.add(o.getTs()));
使用此解決方案,您不必創(chuàng)建新列表,只需修改您擁有的列表。該集合將您要維護(hù)的所有密鑰存儲(chǔ)在列表中。因?yàn)榱斜硪雅判颍宰钚碌膶?duì)象保留在列表中,而其他值則被刪除。
您共享的數(shù)據(jù)的結(jié)果將是:
Obj[ts=2019-05-02T09:00:00Z, generationTs=2019-05-02T21:00:00Z, value=1]
Obj[ts=2019-05-02T09:30:00Z, generationTs=2019-05-02T22:00:00Z, value=5]
Obj[ts=2019-05-02T10:00:00Z, generationTs=2019-05-02T22:00:00Z, value=6]
Obj[ts=2019-05-02T10:30:00Z, generationTs=2019-05-02T21:00:00Z, value=4]
如果您已經(jīng)有一個(gè)排序列表,則此解決方案應(yīng)該是最快的解決方案之一。

TA貢獻(xiàn)1725條經(jīng)驗(yàn) 獲得超8個(gè)贊
下面是一種方法。
將第一個(gè)時(shí)間戳分組,然后使用 maxBy 查找具有最新一代時(shí)間戳的對(duì)象。最后對(duì)第一個(gè)時(shí)間戳進(jìn)行排序并打印出來(lái)。
maxBy 將產(chǎn)生 Optional 的事實(shí)有點(diǎn)難看,但我找不到避免它的方法。
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.maxBy;
import java.time.Instant;
import java.util.Optional;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
public class SortTest {
@Test
public void t() {
final Stream<Obj> s = Stream.of(new Obj("2019-05-02T09:00:00Z", "2019-05-02T21:00:00Z", 1),
new Obj("2019-05-02T09:30:00Z", "2019-05-02T21:00:00Z", 2),
new Obj("2019-05-02T10:00:00Z", "2019-05-02T21:00:00Z", 3),
new Obj("2019-05-02T10:30:00Z", "2019-05-02T21:00:00Z", 4),
new Obj("2019-05-02T09:30:00Z", "2019-05-02T22:00:00Z", 5),
new Obj("2019-05-02T10:00:00Z", "2019-05-02T22:00:00Z", 6));
s.collect(groupingBy(o -> o.ts, maxBy((o1, o2) -> o1.generationTs.compareTo(o2.generationTs))))
.values()
.stream()
.map(Optional::get)
.sorted((o1, o2) -> o1.ts.compareTo(o2.ts))
.forEach(System.out::println);
}
private class Obj {
Instant ts;
Instant generationTs;
int i;
Obj(final String ts, final String generationTs, final int i) {
this.ts = Instant.parse(ts);
this.generationTs = Instant.parse(generationTs);
this.i = i;
}
@Override
public String toString() {
return String.format("%s %s %d", ts, generationTs, i);
}
}
}
添加回答
舉報(bào)