我有如下数组:
int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};我想做的是找到重复的值,然后打印出来。
因此,我的方法是将其转换为ArrayList,然后转换为Set,并在Set上使用stream。
ArrayList<Integer> list = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {
list.add(array[i]);
}
Set<Integer> dup = new HashSet<>(list);然后,我使用一个stream循环它,并打印值使用Collections.frequency。
dup.stream().forEach((key) -> {
System.out.println(key + ": " + Collections.frequency(list, key));
});它当然会把它们全部打印出来,即使计数是1。
我想添加if(key > 1),但这是我想要的值,而不是关键。
如何获得此实例中的值,以便只在何处打印value > 2。
我也许可以放进去:
int check = Collections.frequency(list, key);
if (check > 1) {但是,这与Collections.frequency(list, key)在stream中的复制是非常丑陋的。
发布于 2017-11-17 15:20:15
也许您可以使用filter来获得大于2的值:
dup.stream()
.filter(t -> Collections.frequency(list, t) > 2)
.forEach(key -> System.out.println(key + ": " + Collections.frequency(list, key)));就你的情况而言,结果是:
11: 4编辑
另一种解决办法是:
不需要使用Set或Collections.frequency,您只需使用:
Integer[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
Arrays.stream(array).collect(Collectors.groupingBy(p -> p, Collectors.counting()))
.entrySet().stream().filter(t -> t.getValue() > 1)
.forEach(key -> System.out.println(key.getKey() + ": " + key.getValue()));输出
48: 2
17: 2
11: 4发布于 2017-11-17 15:31:45
不需要在循环中初始化dup并为每个唯一元素调用Collections.frequency的完整示例如下:
Integer[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
List<Integer> list = Arrays.asList(array);
Arrays.stream(array).collect(Collectors.toSet())
.stream()
.map(v -> new SimpleEntry<>(v, Collections.frequency(list, v)))
.filter(v -> v.getValue() > 1)
.forEach(v -> System.out.println(v.getKey() + ":" + v.getValue()));发布于 2017-11-18 23:17:12
Collections.frequency的问题是,它必须遍历所有集合才能找到给定元素的频率。如果您对集合的每个元素都这样做,那么您的解决方案就是O(n^2),即效率极低,因为处理时间随着集合中元素数量的平方而增加。
相反,您可以使用一个流来创建一个映射来计数每个元素的出现情况,如下所示:
int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
Map<Integer, Long> occurrences = Arrays.stream(array)
.boxed()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()));现在,如果您只希望保留值超过1次的值,则只需删除值等于1的映射项。
occurrences.values().removeIf(v -> v == 1);最后,如果您打印地图:
System.out.println(occurrences);您将得到以下输出:
{48=2, 17=2, 11=4}或者,要以您期望的格式获得输出:
occurrences.forEach((k, v) -> System.out.println(k + ": "+ v));另一种方式,短得多,没有流的开销:
Map<Integer, Long> occurrences = new HashMap<>();
for (int n : array) occurrences.merge(n, 1L, Long::sum);然后,删除唯一元素的条目,如前面所示:
occurrences.values().removeIf(v -> v == 1);https://stackoverflow.com/questions/47353687
复制相似问题