使用java流将List <int []>更改为Map <int [],int []>

jeD*_*eDy 2 java java-8 java-stream

假设我有一个

List<int[]> input = ( {1,2,3}, {1,2,4}, 
                {1,2,7}, {1,3,1}, {2,2}, 
                {1,2,8}, {1,3,4}, {2,3})
Run Code Online (Sandbox Code Playgroud)

我需要把它转换成

Map<int[] , int[]> result = { [{1,2} -> {3,4,7,8}] ,
                    [{1,3} -> {1,4}] , 
                    [{2} -> {2,3}]   }
Run Code Online (Sandbox Code Playgroud)

有效地,映射的关键是常见值,直到数组长度为2,值应包含所有这些数组的最后一个元素.

有人可以建议我如何使用java流来获取它,因为在正常的循环中,所有这些都是非常复杂的事情吗?

Tag*_*eev 7

首先,使用数组作为Map键是一个非常糟糕的主意,因为它们hashCodeequals方法基于对象标识,而不是基于数组内容.我建议改为输入数据List<List<Integer>>:

List<List<Integer>> lists = Arrays.asList(Arrays.asList(1,2,3), Arrays.asList(1,2,4),
        Arrays.asList(1,2,7),Arrays.asList(1,3,1),Arrays.asList(2,2),
        Arrays.asList(1,2,8),Arrays.asList(1,3,4),Arrays.asList(2,3));
Run Code Online (Sandbox Code Playgroud)

有了这个,您可以通过级联轻松解决您的任务groupingBy:

Map<List<Integer>, List<Integer>> result = lists.stream().collect(
        Collectors.groupingBy(list -> list.subList(0, list.size() - 1),
            Collectors.mapping(list -> list.get(list.size() - 1),
                Collectors.toList())));
Run Code Online (Sandbox Code Playgroud)

元素按列表前缀(除最后一个之外的所有元素)进行分类,然后在下游缩减期间,提取最后的列表元素并将其收集到列表中.

结果:

System.out.println(result);

{[2]=[2, 3], [1, 2]=[3, 4, 7, 8], [1, 3]=[1, 4]}
Run Code Online (Sandbox Code Playgroud)