Suprita
Suprita

Reputation: 11

How to get number of occurrences of a month from a list of dates in java

Java : I have a list of String which holds Date column data from database. I want the count of each month .

Say I have data : 2021-07-01 2021-08-20 2021-08-25 2021-09-05 2022-01-06 2022-06-07

I want to retrieve value 1 for July,2 for August, 1 for September, 1 for January, 1 for June .

How can I use stream API to achieve this? Or any other method to retrieve vthis data

Upvotes: 0

Views: 409

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 339362

tl;dr

List
.of( "2021-07-01", "2021-08-20", "2021-08-25", "2021-09-05", "2022-01-06", "2022-06-07" )
.stream()
.map( input -> LocalDate.parse( input ) )      // Parse each element as a `LocalDate` object, for a new stream.
.collect(
    Collectors.groupingBy( date -> 
                   YearMonth :: from ,         // Extract a `YearMonth` from each `LocalDate` as the key.
                   Collectors.counting()       // Count occurrences.
    )
)                                              // Return a `Map`.

Details

Make example data.

List< String > inputs = List.of( "2021-07-01", "2021-08-20", "2021-08-25", "2021-09-05", "2022-01-06", "2022-06-07" );

Make a stream of those inputs. Parse each element as a LocalDate object, for a new stream. Produce a key-value Map < YearMonth , Integer > object by extracting a YearMonth from each LocalDate as the key, and summing one as a count of occurrences for the value.

Map< YearMonth , Integer > monthCounts = 
    inputs
        .stream()
        .map( input -> LocalDate.parse( input ) )      // Parse each element as a `LocalDate` object, for a new stream.
        .collect(
            Collectors.groupingBy( date -> 
                           YearMonth :: from  ,        // Extract a `YearMonth` from each `LocalDate` as the key.
                           Collectors.counting()       // Count occurrences.
            )
        )                                              // Return a `Map`.
;

See this code run live at Ideone.com.

{2021-09=1, 2021-08=2, 2021-07=1, 2022-06=1, 2022-01=1}

Sort by year-month: NavigableMap

You might want to keep the entries in your resulting map sorted by the YearMonth keys. If so:

  • Change your declared map type from Map to NavigableMap interface.
  • Add an argument for TreeMap :: new to instantiate an objecting implementing NavigableMap.
NavigableMap < YearMonth, Long > monthCounts =
        inputs
                .stream()
                .map( input -> LocalDate.parse( input ) )
                .collect(
                        Collectors.groupingBy(
                                YearMonth :: from ,
                                TreeMap::new,
                                Collectors.counting()
                        )
                );

Upvotes: 3

ProbablyNotKai
ProbablyNotKai

Reputation: 48

I wrote up a process to allow you to get your desired goal using Streams and Lambdas.

  1. Parse your dates into an Array of LocalDates.

  2. Define a Predicate for your criteria.

  3. Filter your Stream using your Predicate and get the count().

     String[] dates = { "2021-07-01", "2021-08-20", "2021-08-25", "2021-09-05", "2022-01-06", "2022-06-07" };
     LocalDate[] localDates = new LocalDate[dates.length];
    
     for(int i = 0; i < dates.length; i++){
         localDates[i] = LocalDate.parse(dates[i]);
     }
    
     Predicate<LocalDate> month = localDate -> localDate.getMonth().equals(Month.AUGUST);
    
     long count = Arrays.stream(localDates).filter(month).count();
    

Upvotes: 0

Related Questions