簡體   English   中英

Java8:關於Collectors.groupingBy返回的Map元素的順序

[英]Java8: About order of Map elements returned by Collectors.groupingBy

希望就從示例中修改的以下代碼尋求建議。

我想知道更改輸入List元素序列時,結果Map中的輸出序列是否會改變。 但是,似乎輸出在所有情況下都是相同的(我在IDE上反復運行了該程序)。 我是否可以就是否可以預期生成的Map元素的順序尋求建議? 使用枚舉或字符串時,順序(字母/非字母順序)會有所區別嗎,還是元素順序只是隨機的?

public class TestCountry {

    public enum Continent {ASIA, EUROPE}

    String name;
    Continent region;

    public TestCountry (String na, Continent reg) {
        name = na;
        region = reg;
    }

    public String getName () {
        return name;
    }

    public Continent getRegion () {
        return region;
    }

    public static void main(String[] args) {
        List<TestCountry> couList1 = Arrays.asList (
                new TestCountry ("Japan", TestCountry.Continent.ASIA),
                new TestCountry ("Italy", TestCountry.Continent.EUROPE),
                new TestCountry ("Germany", TestCountry.Continent.EUROPE));

        List<TestCountry> couList2 = Arrays.asList (
                new TestCountry ("Italy", TestCountry.Continent.EUROPE),
                new TestCountry ("Japan", TestCountry.Continent.ASIA),
                new TestCountry ("Germany", TestCountry.Continent.EUROPE));

        Map<TestCountry.Continent, List<String>> mapWithRegionAsKey1 = couList1.stream ()
                    .collect(Collectors.groupingBy (TestCountry ::getRegion,
                        Collectors.mapping(TestCountry::getName, Collectors.toList())));

        Map<String, List<Continent>> mapWithNameAsKey1 = couList1.stream ()
                    .collect(Collectors.groupingBy (TestCountry::getName,
                        Collectors.mapping(TestCountry::getRegion, Collectors.toList())));

        Map<TestCountry.Continent, List<String>> mapWithRegionAsKey2 = couList2.stream ()
                    .collect(Collectors.groupingBy (TestCountry ::getRegion,
                        Collectors.mapping(TestCountry::getName, Collectors.toList())));

        Map<String, List<Continent>> mapWithNameAsKey2 = couList2.stream ()
                    .collect(Collectors.groupingBy (TestCountry::getName,
                        Collectors.mapping(TestCountry::getRegion, Collectors.toList())));

        System.out.println("Value of mapWithRegionAsKey1 in couList1: " + mapWithRegionAsKey1);
        System.out.println("Value of mapWithNameAsKey1 in couList1: " + mapWithNameAsKey1);

        System.out.println("Value of mapWithRegionAsKey2 in couList2: " + mapWithRegionAsKey2);
        System.out.println("Value of mapWithNameAsKey2 in couList2: " + mapWithNameAsKey2);
    }
}

/*
 * Output:
Value of mapWithRegionAsKey1 in couList1: {ASIA=[Japan], EUROPE=[Italy, 
Germany]}
Value of mapWithNameAsKey1 in couList1: {Japan=[ASIA], Italy=[EUROPE], 
Germany=[EUROPE]}
Value of mapWithRegionAsKey2 in couList2: {ASIA=[Japan], EUROPE=[Italy, 
Germany]}
Value of mapWithNameAsKey2 in couList2: {Japan=[ASIA], Italy=[EUROPE], 
Germany=[EUROPE]}
 */

Collectors.groupingBy()當前返回一個HashMap 這是一個實現細節,可以在將來的版本中更改。

HashMap的條目未排序,但是它們的迭代順序(在打印HashMap )是確定性的,並且不取決於插入順序。

因此,無論輸入List元素的順序如何,您都會看到相同的輸出。 但是,您不應該依賴該順序,因為它是實現細節。

如果您關心輸出Map條目的順序,則可以修改代碼以生成LinkedHashMap (默認順序為插入順序)或TreeMap (對鍵進行排序)。

順便說一句,如果您將輸入更改為

    List<TestCountry> couList1 = Arrays.asList (
            new TestCountry ("Japan", TestCountry.Continent.ASIA),
            new TestCountry ("Italy", TestCountry.Continent.EUROPE),
            new TestCountry ("Germany", TestCountry.Continent.EUROPE));

    List<TestCountry> couList2 = Arrays.asList (
            new TestCountry ("Germany", TestCountry.Continent.EUROPE),
            new TestCountry ("Italy", TestCountry.Continent.EUROPE),
            new TestCountry ("Japan", TestCountry.Continent.ASIA)
            );

您將在輸出中得到不同的順序:

couList1中mapWithRegionAsKey1的值:{ASIA = [Japan],EUROPE = [ Italy,Germany ]}
couList1中mapWithNameAsKey1的值:{Japan = [ASIA],意大利= [EUROPE],德國= [EUROPE]}
couList2中mapWithRegionAsKey2的值:{ASIA = [Japan],EUROPE = [ Germany,Italy ]}
couList2中mapWithNameAsKey2的值:{Japan = [ASIA],意大利= [EUROPE],德國= [EUROPE]}

這是由於各個輸出List的元素(在當前實現中為ArrayList )是根據插入順序進行排序的,這取決於輸入List的順序。

在質疑之前,請閱讀說明以下內容的文檔:

不保證返回的Map或List對象的類型 ,可變性,可序列化性或線程安全性。

因此,如果您無法確定返回的地圖類型,就無法真正確定將返回的順序(如果有)。 好吧, 正如Eran指出的那樣,它是一個HashMap ,但這不能保證。

問題是您為什么要介意呢? 如果是出於學術目的,那么就有意義,如果不是,那就收集一些可以保證訂單的東西。

Collectors.groupingBy采用一個參數,可讓您指定您可能需要的實際Map實現。

暫無
暫無

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

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