Count frequency of elements in java

Natalie_94 :

I am trying to count the frequency of all dates from a text file. The dates are stored in parsed.get(0) but when I print the frequency I get this output:

1946-01-12: 1
1946-01-12: 1
1946-01-12: 1
1946-01-13: 1
1946-01-13: 1
1946-01-13: 1
1946-01-14: 1
1946-01-14: 1
1946-01-14: 1
1946-01-15: 1

instead of

1946-01-12: 3
1946-01-13: 3
1946-01-14: 3
1946-01-15: 1

I guess it is because I have to store the dates like ("1946-01-12", "1946-01-12", "1946-01-12", "1946-01-12", "1946-01-13", "1946-01-13",...). If I just print parsed.get(0) I get

1946-01-12
1946-01-12
1946-01-12
1946-01-13
1946-01-13
1946-01-13
1946-01-14
1946-01-14
1946-01-14
1946-01-15`

How can I solve it based on my code below?

private static List<WeatherDataHandler> weatherData = new ArrayList<>();
public void loadData(String filePath) throws IOException {

//Read all data
    List<String> fileData = Files.readAllLines(Paths.get("filePath"));
    System.out.println(fileData);

    for(String str : fileData) {
        List<String> parsed = parseData(str);
        LocalDate dateTime = LocalDate.parse(parsed.get(0));

        WeatherDataHandler weather = new WeatherDataHandler(dateTime, Time, temperature, tag);
        weatherData.add(weather);

        List<String> list = Arrays.asList(parsed.get(0));

        Map<String, Long> frequencyMap =
                list.stream().collect(Collectors.groupingBy(Function.identity(), 
                                                        Collectors.counting()));

            for (Map.Entry<String, Long> entry : frequencyMap.entrySet()) {
                System.out.println(entry.getKey() + ": " + entry.getValue());
            }
    }
WJS :

Based on how I think this is working I would do it as follows. Comments included to explain additional logic. The main idea is to do as much inside your main loop as possible. Creating the frequenceyMap outside the loop with a stream is additional and unnecessary work.

    private static List<WeatherDataHandler> weatherData =
            new ArrayList<>();

    public void loadData(String filePath) throws IOException {

        // Read all data
        List<String> fileData =
                Files.readAllLines(Paths.get("filePath"));
        System.out.println(fileData);

        // Pre-instantiate the freqency map.
        Map<String, Long> frequencyMap = new LinkedHashMap<>();

        for (String str : fileData) {

            List<String> parsed = parseData(str);

            LocalDate dateTime =
                    LocalDate.parse(parsed.get(0));

            WeatherDataHandler weather = new WeatherDataHandler(
                    dateTime, Time, temperature, tag);
            weatherData.add(weather);

            // Ensure dateTime is a string.  This may not have the desired
            // format for date but that can be corrected by you
            String strDate = dateTime.toString();

            // Use the compute method of Map. If the count is null,
            // initialize it to 1, otherwise, add 1 to the existing value.
            frequencyMap.compute(strDate,
                    (date, count) -> count == null ? 1 : count + 1);
        }

        for (Map.Entry<String, Long> entry : frequencyMap
                .entrySet()) {
            System.out.println(
                    entry.getKey() + ": " + entry.getValue());
        }
    }

You can also print the map as follows:

frequencyMap.forEach((k,v)->System.out.println(k + ": " + v));

Finally, the above could have been simplified a few places like using Files.lines(path) to create a stream. But as you are also writing this to a WeatherDataHandler list and wanted to keep your structure, I did not use that feature.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=21630&siteId=1