Java 如何从列表中获取元素的组合,如图所示
我有一个Java 如何从列表中获取元素的组合,如图所示,java,arrays,lambda,functional-programming,Java,Arrays,Lambda,Functional Programming,我有一个列表作为索引位置:int[]值 输入: index 0:{1,2} index 1:{1,3,5} index 2:{2} 如何在Java中使用或不使用Lambdas获得以下组合 步骤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}] “要在每个步骤中执
列表
作为索引位置:int[]值
输入:
index 0:{1,2}
index 1:{1,3,5}
index 2:{2}
如何在Java中使用或不使用Lambdas获得以下组合
步骤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个元素子集>其中第一个元素来自第一个数组,第二个来自第二个数组…,>从每个生成的子集中删除重复项。”
无需进一步降低成本
[{1,2}, {1,2}]
到
或
到
但在我的情况下,如果也这样做,则不会影响结果。我假设您希望在不涉及顺序的情况下从每个数组中删除重复项 您可以将每个数组映射到,例如,
LinkedHashSet
,它保持te顺序,但不允许重复。然后只需映射回int[]
并使用收集器进行收集。toList()
:
list=list.stream()
.map(a->Arrays.stream(a).boxed().collect(Collectors.toList())//映射到列表
.map(LinkedHashSet::new)//映射到LinkedHashSet
.map(s->s.stream().mapToInt(i->i.toArray())//映射到int[]
.collect(Collectors.toList());
编辑:当时给出了这个答案,这个问题很模糊,建议解决“删除重复项”问题。不过我会记住这个答案,因为它可能包含对其他人有用的信息
很难说出问题的确切解决方案,因为您没有正确描述输入和想要的输出。仅仅发布一个例子是不够的
因此,让我们假设如下:
- 输入:整数数组的列表(
)list
- 输出:整数数组的列表(
),其中第n个数组包含输入列表第n个数组的值,但删除了重复项list
List<int[]> output = new ArrayList<>(input.size());
for(int[] item : input) {
output.add(removeDuplicates(item));
}
(另见)
当然,如果您可以有一个列表作为输入和输出,那么一切都会容易得多。在这种情况下,事情可以很容易地做到如下:
List<Collection<Integer>> output = new ArrayList<>(input.size());
for(Collection<Integer> item : input) {
output.add(new HashSet<Integer>(item));
}
List output=newarraylist(input.size());
用于(收集项目:输入){
添加(新哈希集(项));
}
使用Java 8流式API
完整性方面:Java 8流式API使生活更加轻松,即使使用List
:
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());
List output=input.stream()
.map(项->数组.stream(项).distinct().toArray())
.collect(Collectors.toList());
您所问的似乎是N个集合的笛卡尔积(Set1 x Set2 x…x SetN
)
不幸的是,Java中没有一个标准方法可以让我们轻松地构建一个,但是在没有Guava及其方法的帮助下,这项任务似乎相当容易
唯一的条件是我们需要提供它的参数List
因为这个答案基于这样一个假设,即每个int[]都可以被视为set,这意味着它的值必须是唯一的。实际上,更准确地说,如果索引0
将是{1,2,1}
或{1,2,2}
它将按设置{1,2}
进行处理
下面是一个带有当前数据的列表示例
(toList
是静态导入的Collections.toList()
方法,类似地toSet
):
如果您正在寻找将列表
转换为列表
的方法,以下是一个示例:
private static List<Set<Integer>> convert(List<int[]> list) {
return list
.stream()
.map(arr ->
IntStream.of(arr)
.mapToObj(Integer::valueOf)// same as .boxed()
.collect(toSet())
).collect(toList());
}
私有静态列表转换(列表){
返回列表
.stream()
.map(arr->
IntStream.of(arr)
.mapToObj(Integer::valueOf)//与.boxed()相同
.collect(toSet())
).collect(toList());
}
这不是Java语法意义上的列表
对象。请您发布创建此列表的代码或至少描述此列表的结构,并描述您称之为“减少”的规则。我不知道第二个列表与第一个列表有什么关系!请发表你的文章并改正你的例子。有时,不同的操作可能导致相同的输出。因此,我们不希望假设您正在尝试做什么,因此您应该精确地确定在每个步骤中要做什么,例如从n个数组生成所有n个元素子集,其中第一个元素来自第一个数组,第二个元素来自第二个数组…,从每个生成的子集中删除重复项。另外,您是否希望删除重复的子集,例如,如果您将有{1,2}{1,2}
,或者甚至可能是{1,2}{2,1}
?您的每个步骤都应该是单独的问题(可能已经问过了,所以现在请尝试搜索资源)。不管怎样,我们仍然不知道非常重要的信息,即:数组的数量总是3还是更多?根据这些信息,我们可以选择是否只使用三个循环(或内部流)或是否需要一些递归解决方案。我们可以假设每个int[]
包含唯一的数字吗?换句话说,是否可以索引0:
是{1,1,2}
?我已经编辑了这个问题,希望您理解我的意图。我不关心从数组中删除重复项。我想要列表中所有n个索引的所有可能的唯一组合。比如说,0索引有一个由元素1,2组成的整数数组,1索引有元素1,3,5,2索引有元素2。所以这里我想要的组合是1,1,2 | 1,3,2 | 1,5,2
。现在在这个输出中,第一个集合1,1,2具有与1相同的两个元素。所以,我想把它变成1,2。现在我将有1,2 | 1,3,2 | 1,5,2
。同样,当我取0索引中的第二个元素2并检索组合时,我将得到2,1,2 | 2,3,2 | 2,5,2
。最后,我希望通过删除2将其设置为2,1 | 2,3 | 2,5
List<int[]> output = new ArrayList<>(input.size());
for(int[] item : input) {
output.add(removeDuplicates(item));
}
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;
}
List<Collection<Integer>> output = new ArrayList<>(input.size());
for(Collection<Integer> item : input) {
output.add(new HashSet<Integer>(item));
}
List<int[]> output = input.stream()
.map(item -> Arrays.stream(item).distinct().toArray())
.collect(Collectors.toList());
//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]]
private static List<Set<Integer>> convert(List<int[]> list) {
return list
.stream()
.map(arr ->
IntStream.of(arr)
.mapToObj(Integer::valueOf)// same as .boxed()
.collect(toSet())
).collect(toList());
}