java - 我们如何使用 map 从双精度数组中获取唯一元素‽
问题描述
我目前正在解决以下编程练习:查找唯一编号语句是:
有一个带有一些数字的数组。除了一个,所有数字都相等。试着找到它!
Kata.findUniq(new double[]{ 1, 1, 1, 2, 1, 1 }); // => 2 Kata.findUniq(new double[]{ 0, 0, 0.55, 0, 0 }); // => 0.55
保证数组包含 3 个以上的数字。
测试包含一些非常大的数组,因此请考虑性能。
首先我的想法是将所有元素的频率作为映射,然后返回频率值仅为 1 的键。
我写了以下内容:
import java.util.stream.*;
public class Kata {
public static double findUniq(double arr[]) {
Map<Double, Long> frequencies = Arrays.stream(arr)
.collect(Collectors.groupingBy(n -> n, Collectors.counting()));
System.out.println("Map: "+map);
}
}
所以它输出:
./src/main/java/Kata.java:8: error: method collect in interface DoubleStream cannot be applied to given types;
.collect(Collectors.groupingBy(n -> n, Collectors.counting()));
^
required: Supplier<R>,ObjDoubleConsumer<R>,BiConsumer<R,R>
found: Collector<Object,CAP#1,Map<Object,Long>>
reason: cannot infer type-variable(s) R
(actual and formal argument lists differ in length)
where R is a type-variable:
R extends Object declared in method <R>collect(Supplier<R>,ObjDoubleConsumer<R>,BiConsumer<R,R>)
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
./src/main/java/Kata.java:10: error: cannot find symbol
System.out.println("Map: "+map);
^
symbol: variable map
location: class Kata
2 errors
我想解决这个问题的方法是理解:
required: Supplier<R>,ObjDoubleConsumer<R>,BiConsumer<R,R>
found: Collector<Object,CAP#1,Map<Object,Long>>
我确实知道它期望:Supplier<R>,ObjDoubleConsumer<R>,BiConsumer<R,R>
而且我正在写作:Collector<Object,CAP#1,Map<Object,Long>>
但它是什么意思?我们怎样才能解决它?为什么会生成?
然后我尝试了第二种方法:使用 HashSet 获取所有不同的双精度数,然后删除不唯一的双精度数,并返回存储在 HashSet 中的唯一双精度数。
import java.util.*;
import java.util.stream.*;
public class Kata {
public static double findUniq(double arr[]) {
System.out.println("\nOriginal array: "+Arrays.toString(arr));
Set<Double> unique = new HashSet<Double>();
double repeated = Double.MIN_VALUE;
for(int i = 0; i < arr.length; i++){
if(repeated != arr[i] && !unique.add(arr[i])){
repeated = arr[i];
}
}
unique.remove(repeated);
System.out.println("Set: "+Arrays.toString(unique.toArray()));
return (double)unique.toArray()[0];
}
}
我的问题是,我们如何才能实现返回唯一元素,使用第一种方法,用地图计算频率,然后返回值为 1‽ 的键。
我也读过:
解决方案
发生编译器错误是因为Collector
您使用的 s 不起作用-原始sDoubleStream
的专用类型。你可以做的是把它变成第一个,然后应用:Stream
double
DoubleStream
Stream<Double>
Collector
Map<Double, Long> frequencies = Arrays.stream(arr)
.boxed() // this is the key method to call
.collect(Collectors.groupingBy(n -> n, Collectors.counting()));
然后你需要找到值为 1 的 KVP,但地图并不是真的为此而设计的:
System.out.println("Map: "+
frequencies.entrySet().stream()
.filter(x -> x.getValue() == 1)
.findFirst().get().getKey());
请注意,有比这更快的解决方案。请记住,只有一个双打是不同的!
推荐阅读
- android - Android 标题栏图标被裁剪
- html - CSS 与 HTML 的集成
- java - 如何使用 post 方法重定向 servlet post 请求另一个服务器 url
- android - 将向上滑动和向下滑动侦听器添加到水平 recyclerView
- java - 如何使用 API java.util.concurrent.Future 而不是在 Java 中显式创建线程?
- ios - 监控区域不适用于 KVO
- oracle - How can i set a maxiumum value using list agg
- optimization - SCIP符号的作用是什么?
- php - 如何在 PHP 中使用带有 SimpleXML 的数组仅显示 XML 文件中的特定数据?
- rust - 泛型加动态调度