Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java stream individual numbers to a range

I want to transform pairs of numbers to a range of integers so I can perform functions on them. for example each of these lines:

1-4
5-6
1-2
4-7

should be transformed to array i.e: [1,2,3,4]. my goal is to do a count on the most frequent number. i am trying to do it like the word count example, but the problem is how to create the range stream from the two numbers in each line?

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()));
like image 899
user1450410 Avatar asked Sep 20 '18 17:09

user1450410


1 Answers

The following pipeline splits each line on -, then uses IntStream to create a range of numbers between the two.

The result is a flatten stream of all these inner integers, followed by a counting group by (number). The max "count" is then found on the values of this map.

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);

With your example data, it prints 1=2 (1 found 2 times) - there are many values found exactly twice.

like image 136
ernest_k Avatar answered Oct 21 '22 15:10

ernest_k