我想把数字对转换成整数的范围,这样我就可以对它们执行函数了。例如,这些行中的每一行:
1-4
5-6
1-2
4-7应该转换为数组,即: 1,2,3,4。我的目标是对最频繁的数字进行计数。我试着像单词计数示例那样做,但是问题是如何从每行的两个数字创建范围流?
Path path = Paths.get(args[0]);
Map<String, Long> wordCount = Files.lines(path)
.flatMap(line -> Arrays.stream(line.trim().split("-")))
.
.map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
.filter(num -> num.length() > 0)
.map(number -> new SimpleEntry<>(number, 1))
.collect(Collectors.groupingBy(SimpleEntry::getKey, Collectors.counting()));发布于 2018-09-20 18:09:07
下面的管道将-上的每一行拆分,然后使用IntStream在两者之间创建一个数字范围。
结果是所有这些内部整数的平坦流,然后是计数组(number)。然后在此映射的值上找到最大“计数”。
String s = "1-4\n" + "5-6\n" + "1-2\n" + "4-7"; //simpler version with inline text
Optional<Entry<Integer, Long>> result =
Stream.of(s.split("\n")) //replace with Files.lines(path) for real stream
.map(line -> line.split("-"))
.map(array -> new int[] { Integer.parseInt(array[0].trim()),
Integer.parseInt(array[1].trim()) })
.map(array -> IntStream.rangeClosed(array[0], array[1]))
.flatMapToInt(Function.identity())
.boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.max(Comparator.comparingLong(Entry::getValue));
result.ifPresent(System.out::println);使用示例数据,它会打印1=2 (1 found 2次)--有许多值精确地找到了两次。
发布于 2018-09-20 18:46:36
如果您想以最大频率查看所有数字,可以这样做:
private static List<Integer> findMaxOccurs(String... ranges) {
return Optional
.ofNullable(
Arrays.stream(ranges)
.map(r -> r.split("-"))
.flatMap(r -> IntStream.rangeClosed(Integer.parseInt(r[0]),
Integer.parseInt(r[1]))
.boxed())
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
// We now have Map<Integer, Long> mapping Number to Frequency
.entrySet()
.stream()
.collect(Collectors.groupingBy(Entry::getValue, TreeMap::new,
Collectors.mapping(Entry::getKey, Collectors.toList())))
// We now have TreeMap<Long, List<Integer>> mapping Frequency to Numbers
.lastEntry()
)
.map(Entry::getValue)
.orElse(Collections.emptyList());
}测试
System.out.println(findMaxOccurs("1-4", "5-6", "1-2", "4-7"));输出
[1, 2, 4, 5, 6]如果您也想知道这些数字的频率,最好将其分为两种方法:
private static Entry<Long, List<Integer>> findMaxOccurring(String... ranges) {
return Arrays.stream(ranges)
.map(r -> r.split("-"))
.flatMap(r -> IntStream.rangeClosed(Integer.parseInt(r[0]),
Integer.parseInt(r[1])).boxed())
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
// We now have Map<Integer, Long> mapping Number to Frequency
.entrySet()
.stream()
.collect(Collectors.groupingBy(Entry::getValue, TreeMap::new,
Collectors.mapping(Entry::getKey, Collectors.toList())))
// We now have TreeMap<Long, List<Integer>> mapping Frequency to Numbers
.lastEntry();
}private static List<Integer> findMaxOccurringNumbers(String... ranges) {
return Optional.ofNullable(findMaxOccurring(ranges))
.map(Entry::getValue)
.orElse(Collections.emptyList());
}测试
System.out.println(findMaxOccurring("1-4", "5-6", "1-2", "4-7"));
System.out.println(findMaxOccurringNumbers("1-4", "5-6", "1-2", "4-7"));输出
2=[1, 2, 4, 5, 6]
[1, 2, 4, 5, 6]https://stackoverflow.com/questions/52430539
复制相似问题