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

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

在這種情況下如何對列表進行流式排序?

在這種情況下如何對列表進行流式排序?

交互式愛情 2022-11-10 15:03:19
我在 Java 中有一個帶有兩個時間戳的對象列表,例如:Obj(TimeStamp ts,TimeStamp generationTs,int 值)。最后,我不希望列表中的兩個項目具有相同的 ts。如果有的話,我只想保留最新一代 T 的那個。實際上,我有那個代碼,它可以工作,但我想知道如果使用流,我不能做更好的事情嗎?list.sort(Collections.reverseOrder());List<Obj> returnedList = Lists.newArrayList();if (!list.isEmpty()) {   returnedList.add(list.get(0));   Iterator<Obj> i = list.iterator();   while (i.hasNext()) {       Obj lastObj = returnedList.get(returnedList.size() - 1);       Obj nextObj = i.next();       if (!lastObj.getTs().isEqual(nextObj.getTs())) {           returnedList.add(nextObj);       } else {           if (lastObj.getGenerationTs().isBefore(nextObj.getGenerationTs())) {             returnedList.remove(lastObj);             returnedList.add(nextObj);           }        }    }}如果列表是:{("2019-05-02T09:00:00Z", "2019-05-02T21:00:00Z", 1),("2019-05-02T09:30:00Z", "2019-05-02T21:00:00Z", 2),("2019-05-02T10:00:00Z", "2019-05-02T21:00:00Z", 3),("2019-05-02T10:30:00Z", "2019-05-02T21:00:00Z", 4),("2019-05-02T09:30:00Z", "2019-05-02T22:00:00Z", 5),("2019-05-02T10:00:00Z", "2019-05-02T22:00:00Z", 6) }它必須返回:{("2019-05-02T09:00:00Z", "2019-05-02T21:00:00Z", 1),("2019-05-02T09:30:00Z", "2019-05-02T22:00:00Z", 5),("2019-05-02T10:00:00Z", "2019-05-02T22:00:00Z", 6) ("2019-05-02T10:30:00Z", "2019-05-02T21:00:00Z", 4) }
查看完整描述

4 回答

?
慕森王

TA貢獻1777條經驗 獲得超3個贊

你可以這樣嘗試:


Map<TimeStamp, Optional<Obj>> result = 

         list.stream().collect(Collectors.groupingBy(

                                Obj::getTs,

                                Collectors.maxBy(Comparator.comparing(Obj::getGenerationTs))

         ));

正如@Naman 在評論中所說的更完整的選項:


list.stream().collect(Collectors.groupingBy(

                       Obj::getTs,

                       Collectors.maxBy(Comparator.comparing(Obj::getGenerationTs))

              )).values().stream()

                .filter(Optional::isPresent) 

                .map(Optional::get)

                .collect(Collectors.toList());


查看完整回答
反對 回復 2022-11-10
?
森欄

TA貢獻1810條經驗 獲得超5個贊

您當然可以Stream使用地圖收集器然后獲取值來做到這一點


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())));


查看完整回答
反對 回復 2022-11-10
?
HUX布斯

TA貢獻1876條經驗 獲得超6個贊

如果您已經有一個排序列表(按 降序generationTs),就像您在示例代碼中那樣,您可以使用 aHashSet和Collection.removeIf()從該列表中刪除所有重復的時間戳:


list.sort(Comparator.comparing(Obj::getTs)

        .thenComparing(Comparator.comparing(Obj::getGenerationTs)

                .reversed()));


Set<Timestamp> keys = new HashSet<>();

list.removeIf(o -> !keys.add(o.getTs()));

使用此解決方案,您不必創建新列表,只需修改您擁有的列表。該集合將您要維護的所有密鑰存儲在列表中。因為列表已排序,所以最新的對象保留在列表中,而其他值則被刪除。


您共享的數據的結果將是:


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]

如果您已經有一個排序列表,則此解決方案應該是最快的解決方案之一。


查看完整回答
反對 回復 2022-11-10
?
qq_遁去的一_1

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

下面是一種方法。


將第一個時間戳分組,然后使用 maxBy 查找具有最新一代時間戳的對象。最后對第一個時間戳進行排序并打印出來。


maxBy 將產生 Optional 的事實有點難看,但我找不到避免它的方法。


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);

    }

}

}


查看完整回答
反對 回復 2022-11-10
  • 4 回答
  • 0 關注
  • 173 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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