我有一个List<int[]>
作为index_position:int[] values
input:
index 0:{1,2}
index 1:{1,3,5}
index 2:{2}
如何使用或不使用Lambdas在Java中获得以下组合。
第1步:找到所有这些组合
[{1,1,2}, {1,3,2}, {1,5,2}, {2,1,2}, {2,3,2}, {2,5,2}]
->
步骤2:从被删除的组合中删除重复项
[{1,2}, {1,3,2}, {1,5,2}, {2,1}, {2,3}, {2,5}]
“想要在每个步骤中执行,例如从n个数组生成所有n个元素子集&gt;其中第一个元素来自第一个数组,第二个来自第二个数组......,&gt;从每个结果子集中删除重复项。”
不需要进一步减少
[{1,2}, {1,2}]
到
[{1,2}]
或
[{1,2},{2,1}]
到
[{1,2}] / [{2,1}]
但如果完成,也不会影响我的结果。
答案 0 :(得分:3)
你所问的似乎是N套(#import <NotificationCenter/NotificationCenter.h>
@interface ViewController () <NCWidgetProviding> {...}
)的笛卡尔积。
不幸的是,Java中没有标准的方法可以让我们轻松地构建一个,但是在Guava及其Sets.cartesianProduct
方法的帮助下,这个任务似乎很容易。
只有条件是我们需要提供Set1 x Set2 x ... x SetN
作为参数
因此,这个答案是基于每个int []被视为集合的假设,这意味着它的值必须是唯一的。实际上,如果List<Set<..>>
为index 0
或{1,2,1}
,则会更精确地将其设置为{1,2,2}
。
以下为{1,2}
示例,其中包含您当前的数据
(List<Set<Integer>>
是静态导入的toList
方法,类似地Collections.toList()
):
toSet
输出:
//part 0: preparing data
List<Set<Integer>> sets = new ArrayList<>(
Arrays.asList(
new HashSet<>(Arrays.asList(1, 2)),
new HashSet<>(Arrays.asList(1, 3, 5)),
new HashSet<>(Arrays.asList(2))
)
);
sets.forEach(System.out::println);
System.out.println("-----------------");
//part 1: calculating cartesian products
Set<List<Integer>> cartesianProducts = Sets.cartesianProduct(sets);
System.out.println(cartesianProducts);
System.out.println("-----------------");
//part 2
List<List<Integer>> noDuplicatesInProducts = cartesianProducts
.stream()//iterate over each cartesian product
.map(product -> product.stream()
.distinct()//remove duplicate values
.collect(toList())//store updated product as list
).collect(toList());//store all products as list
System.out.println(noDuplicatesInProducts);
如果您正在寻找将[1, 2]
[1, 3, 5]
[2]
-----------------
[[1, 1, 2], [1, 3, 2], [1, 5, 2], [2, 1, 2], [2, 3, 2], [2, 5, 2]]
-----------------
[[1, 2], [1, 3, 2], [1, 5, 2], [2, 1], [2, 3], [2, 5]]
转换为List<int[]>
的方法,请参阅以下示例:
List<Set<Integer>>
答案 1 :(得分:2)
编辑:当时,给出了这个答案,问题含糊不清,并建议删除重复内容&#39;问题。我会保留这个答案,因为它可能包含其他人的有用信息。
由于您没有正确描述输入和想要的输出,很难说出问题的准确解决方案。只发布一个例子就不够了。
所以让我们假设以下内容:
输入:整数数组列表(List<int[]>
)。
输出:整数数组列表(List<int[]>
),其中第n 数组包含 n的值-th 输入列表的数组,但删除了重复项。
将输入列表中的项目复制到新的输出列表中很简单:
List<int[]> output = new ArrayList<>(input.size());
for(int[] item : input) {
output.add(removeDuplicates(item));
}
因此可以将问题简化为从int[]
删除重复项。这可以通过使用中间Set<Integer>
轻松解决,因为Set
默认情况下没有重复项。不幸的是,int[]
无法直接放入HashSet<Integer>
,反之亦然,因此我们必须手动复制元素:
public int[] removeDuplicates(int[] input) {
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < input.length; i++)
set.add(input[i]);
int[] output = new int[set.size()];
int i = 0;
for (Integer e : set) {
output[i++] = e;
}
return output;
}
(另见How to efficiently remove duplicates from an array without using Set)
如果您可以输入List<Collection<Integer>>
作为输入和输出,那么一切都要容易得多。在这种情况下,事情可以很容易地完成如下:
List<Collection<Integer>> output = new ArrayList<>(input.size());
for(Collection<Integer> item : input) {
output.add(new HashSet<Integer>(item));
}
使用Java 8流媒体API
为了完整性:Java 8流API使生活变得更加轻松,即使使用List<int[]>
:
List<int[]> output = input.stream()
.map(item -> Arrays.stream(item).distinct().toArray())
.collect(Collectors.toList());
答案 2 :(得分:-1)
我假设您要在不触及订单的情况下从每个数组中删除重复项。
您可以将每个数组映射到例如LinkedHashSet
,它保留了订单但不允许重复。然后,只需回到int[]
并使用Collectors.toList()
收集:
list = list.stream()
.map(a -> Arrays.stream(a).boxed().collect(Collectors.toList())) // map to List<Integer>
.map(LinkedHashSet::new) // map to LinkedHashSet<Integer>
.map(s -> s.stream().mapToInt(i -> i).toArray()) // map to int[]
.collect(Collectors.toList());