Java 8 删除值以仅保留N个引用
我今天做了一些《暗战》中的卡塔。我必须编写一个函数,从数组中只保留N个相同的元素,例如:Java 8 删除值以仅保留N个引用,java-8,java-stream,Java 8,Java Stream,我今天做了一些《暗战》中的卡塔。我必须编写一个函数,从数组中只保留N个相同的元素,例如: {1,2,3,4,1}, N=1 -> {1,2,3,4} {2,2,2,2}, N=2 -> {2,2} 我使用streams提出了该解决方案: public static int[] deleteNth(int[] elements, int maxOcurrences) { List<Integer> ints = Arrays.stream(elements)
{1,2,3,4,1}, N=1 -> {1,2,3,4}
{2,2,2,2}, N=2 -> {2,2}
我使用streams提出了该解决方案:
public static int[] deleteNth(int[] elements, int maxOcurrences) {
List<Integer> ints = Arrays.stream(elements)
.boxed()
.collect(Collectors.toList());
return ints.stream().filter(x -> Collections.frequency(ints, x) <= maxOcurrences)
.mapToInt(Integer::intValue)
.toArray();
}
public static int[]deleteNth(int[]元素,int maxoccurrences){
List ints=Arrays.stream(元素)
.boxed()
.collect(Collectors.toList());
return ints.stream().filter(x->Collections.frequency(ints,x)实际上您排除了优于maxOcurrences
值的元素:
.filter(x -> Collections.frequency(ints, x) <= maxOcurrences)
输出:
[1,2,3,4]
[2,2]
我发现完成手头任务的解决方案如下:
public static int[] deleteNth(int[] elements, int maxOccurrences) {
return Arrays.stream(elements)
.boxed()
.collect(Collectors.groupingBy(Function.identity(),
LinkedHashMap::new,
Collectors.counting()))
.entrySet()
.stream()
.flatMapToInt(entry ->
IntStream.generate(entry::getKey)
.limit(Math.min(maxOccurrences, entry.getValue())))
.toArray();
}
我们首先对元素进行分组,然后应用一个Collectors.counting()
作为下游收集器,获取给定元素的计数。完成后,我们只需将给定数量的n
映射多次,然后使用toArray
急切操作收集到一个数组。我认为这是一个不使用流的好例子。流并不总是有状态操作的最佳方法这涉及到许多人
但是这是绝对可以做到的,而且这个问题特别针对流,所以您可以使用以下内容
使用forEachOrdered
您可以使用forEachOrdered
,以确保顺序(显然,流必须是顺序的)
这个收集器
创建一个数组列表
,当添加新元素时,检查是否满足maxOcurrences
,如果不满足,则添加元素。如前所述,在下面的回答中,根本不调用组合器。这比n^2
好一点
可以找到为什么在序列流中不调用组合器方法的更多信息。这不能保证顺序,这可能是必需的。@JoseDaSilva您有它。不,我是指元素的顺序,例如n=2
和{2,3,2,2,2}
,这里的输出应该是{2,2,3}
,但应该是{2, 3, 2}
?,我们还不知道。我要保存这个简洁的收集技巧,谢谢你的解决方案。基本上,你是在检查列表中的元素是否少于N个,并在为真时添加它们,对吗?你能解释一下为什么我的方法不起作用吗?你的方法不起作用,因为你检查的是所有元素,而不仅仅是你之前拥有的元素这一点。例如,使用{2,2,2,2}
,如果你对照孔列表进行检查,你会得到4次重复,并且在过滤器中你会将它们全部丢弃。如果你改为从{}
开始,然后添加2
,第一次检查重复是0{2}
,然后添加另一次2
,检查重复是1{2,2}
,最后要添加另一个2
,首先检查重复2是的,超出限制的事件应被丢弃,并且应保持顺序
public static int[] deleteNth(int[] elements, int maxOccurrences) {
return Arrays.stream(elements)
.boxed()
.collect(Collectors.groupingBy(Function.identity(),
LinkedHashMap::new,
Collectors.counting()))
.entrySet()
.stream()
.flatMapToInt(entry ->
IntStream.generate(entry::getKey)
.limit(Math.min(maxOccurrences, entry.getValue())))
.toArray();
}
public static int[] deleteNth(int[] elements, int maxOcurrs) {
List<Integer> list = new ArrayList<>();
Arrays.stream(elements).forEachOrdered(elem -> {
if (Collections.frequency(list, elem) < maxOcurrs) list.add(elem);
});
return list.stream().mapToInt(Integer::intValue).toArray();
}
public static int[] deleteNth(int[] elements, int maxOcurrs) {
return Arrays.stream(elements).boxed()
.collect(() -> new ArrayList<Integer>(),
(list, elem) -> {
if (Collections.frequency(list, elem) < maxOcurrs) list.add(elem);
},
(list1, list2) -> {
throw new UnsupportedOperationException("Undefined combiner");
})
.stream()
.mapToInt(Integer::intValue)
.toArray();
}