簡體   English   中英

如何以優雅的方式使用 Java8 返回 map<object, long> 來自列表<object>計數發生?<div id="text_translate"><p> 我知道標題很拗口,所以我將嘗試用一個例子來解釋。</p><p> 我有一個清單。 Chores 有一個 id 字段作為標識符,但列表將包含許多家務,其中一些將具有相同的 ID。 我的目標是返回一個 Map&lt;Chore, Long&gt; ,其中 long 將計算雜務的出現次數。 例如:</p><pre> List&lt;Chore&gt; choreList = new ArrayList&lt;Chore&gt;(); choreList.add(new Chore("1", "vacuum", "7-6-22"); //Numbers 1,2,3 are the ID's for each chore choreList.add(new Chore("2", "dusting", "7-1-22"); choreList.add(new Chore("3", "mowing", "7-15-22"); choreList.add(new Chore("1", "vacuum", "7-14-22"); choreList.add(new Chore("1", "vacuum", "7-18-22"); choreList.add(new Chore("2", "dusting", "7-24-22");</pre><p> 使用此列表和 Java8 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ function,我想返回一個 Map&lt;Chore, Long&gt;,其中包含家務 object 和事件。 因此,對於 ID 為“1”的雜項,長為 3。對於 ID 為“2”的雜項,長為 2……等等。</p><p> 我試圖為此找到一個優雅的解決方案,但看起來每個人都可以得到如下內容:</p><pre> Map&lt;String, Long&gt; choresById = chores.stream().collect(Collectors.groupingBy(Chore::getId, Collectors.counting()));</pre><p> 我怎樣才能想出 Map&lt;Chore, Long&gt; 而不是 Map&lt;String, Long&gt; (在這種情況下,字符串是 ID?)</p></div></object></object,>

[英]How to use Java8 in an elegant way to return a map of <Object, Long> from a List<Object> counting occurrence?

我知道標題很拗口,所以我將嘗試用一個例子來解釋。

我有一個清單。 Chores 有一個 id 字段作為標識符,但列表將包含許多家務,其中一些將具有相同的 ID。 我的目標是返回一個 Map<Chore, Long> ,其中 long 將計算雜務的出現次數。 例如:

List<Chore> choreList = new ArrayList<Chore>();
choreList.add(new Chore("1", "vacuum", "7-6-22");  //Numbers 1,2,3 are the ID's for each chore
choreList.add(new Chore("2", "dusting", "7-1-22");
choreList.add(new Chore("3", "mowing", "7-15-22");
choreList.add(new Chore("1", "vacuum", "7-14-22");
choreList.add(new Chore("1", "vacuum", "7-18-22");
choreList.add(new Chore("2", "dusting", "7-24-22");

使用此列表和 Java8 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ function,我想返回一個 Map<Chore, Long>,其中包含家務 object 和事件。 因此,對於 ID 為“1”的雜項,長為 3。對於 ID 為“2”的雜項,長為 2……等等。

我試圖為此找到一個優雅的解決方案,但看起來每個人都可以得到如下內容:

    Map<String, Long> choresById = chores.stream().collect(Collectors.groupingBy(Chore::getId, Collectors.counting()));

我怎樣才能想出 Map<Chore, Long> 而不是 Map<String, Long> (在這種情況下,字符串是 ID?)

因為Chore被用作Map中的鍵,所以它應該實現基於身份的equals() (和hashCode() )。 這也滿足了使用groupBy()進行分區的要求,因此您可以使用Function.identity()作為密鑰提取器。

Map<Chore, Long> choreCounts = chores.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

在回答后續問題時,

Chores 上還有其他屬性,我需要根據 Id 來計算它們。 在這種情況下,分區仍然有效嗎?

是的,如果equals()是基於身份的,它仍然可以工作。 但是,您的 model 似乎有缺陷。

作為附加Chore項屬性示例添加的屬性似乎是一個日期,我猜這里的想法是每個Chore項記錄在某個日期完成的雜項。 其他信息可能包括誰做了家務或花了多長時間。

如果這個猜測是正確的,我建議創建單獨的類來表示家務本身和家務的性能:

class Chore {

    private final long id;
    private final String name;

    Chore(long id, String name) {
       if (id < 1) throw new IllegalArgumentException("id < 1: " + id);
       this.id = id;
       this.name = Objects.requireNonNull(name);
    }

    @Override
    public final int hashCode() {
       return Long.hashCode(id);
    }

    @Override
    public final boolean equals(Object obj) {
        return obj == this || obj instanceof Chore that && that.id == this.id;
    }

}

class ChoreRecord {
  
    private final Chore chore;
    private final LocalDate datePerformed;

    ...

    Chore getChore() {
      return chore;
    }

    ...

}

這里的想法是,您實際上只需要一個吸塵任務實例,一個除塵任務等。但是許多ChoreRecord實例可以指向同一個Chore任務實例,等等。

然后,您將從List<ChoreRecord>生成Map<Chore, Long> ,並按每個ChoreRecord中的Chore進行分組:

Map<Chore, Long> choreCounts = choreRecords.stream()
    .collect(Collectors.groupingBy(ChoreRecord::getChore, Collectors.counting()));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM