Monday, 29 September 2014

Java 8 - using collect in the Stream API

The following code povides some examples how to do collect() in the Java Stream API.



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.cert.PKIXRevocationChecker.Option;
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 *
 * @author José
 */
public class DataAndTime {

    public static void main(String[] args) {

        List<Person> persons = new ArrayList<>();
        
        try (
            BufferedReader reader = 
                new BufferedReader(
                    new InputStreamReader(
                        DataAndTime.class.getResourceAsStream("people.txt")));
            Stream<String> stream = reader.lines();
        ) {
            
            stream.map(
               line -> {
                   String[] s = line.split(" ");
                   String name = s[0].trim();
                   int year = Integer.parseInt(s[1]);
                   Month month = Month.of(Integer.parseInt(s[2]));
                   int day = Integer.parseInt(s[3]);
                   Person p = new Person(name, LocalDate.of(year, month, day));
                   persons.add(p);
                   return p;
               })
               .forEach(System.out::println);
            
            Optional<Person>opt = persons.stream().filter(p -> p.getAge() >= 20)
            .min(Comparator.comparing(Person::getAge));
            
            System.out.println("Youngest person among all persons: " + opt); 
            
            Optional<Person>optSecond = persons
              .stream()
              .max(Comparator.comparing(Person::getAge)); 
            
            System.out.println("Oldest person among all persons: " + optSecond);    
            
            Map<Integer, Long> map = 
              persons.stream()
              .collect(Collectors.groupingBy(
                Person::getAge, Collectors.counting())); 
            
            System.out.println(map);
            
            Map<Integer, List<String>> mapSecond = 
              persons.stream()
              .collect(Collectors.groupingBy(
                Person::getAge, 
                Collectors.mapping(
                  Person::getName,
                  Collectors.toList()
                  )
                )); 
            
            System.out.println(mapSecond);
            
            Map<Integer, Set<String>> mapThird = 
              persons.stream()
              .collect(Collectors.groupingBy(
                Person::getAge, 
                Collectors.mapping(
                  Person::getName,
                  Collectors.toCollection(TreeSet::new)
                  )
                )); 
            
            System.out.println(mapThird);
            
            Map<Integer, String> mapFourth = 
              persons.stream()
              .collect(Collectors.groupingBy(
                Person::getAge, 
                Collectors.mapping(
                  Person::getName,
                  Collectors.joining(", ")
                  )
                )); 
            
            System.out.println(mapFourth);
            
            
            
        } catch (IOException ioe) {
            System.out.println(ioe);
        }

        LocalDate now = LocalDate.of(2014, Month.MARCH, 12);
        
        persons.stream().forEach(
                p -> {
                    Period period = Period.between(p.getDateOfBirth(), now);
                    System.out.println(p.getName() + " was born " +
                            period.get(ChronoUnit.YEARS) + " years and " + 
                            period.get(ChronoUnit.MONTHS) + " months " + 
                            "[" + p.getDateOfBirth().until(now, ChronoUnit.MONTHS) 
                            + " months]"
                            );
                    
                });
    }
}

The definition of Person class:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */


import java.time.LocalDate;
import java.time.chrono.IsoChronology;

/**
 *
 * @author José
 */
public class Person {
    
    private String name;
    private LocalDate dateOfBirth;
    
    public Person(){}
    
    public Person(String name, LocalDate dateOfBirth) {
        this.name = name;
        this.dateOfBirth = dateOfBirth;
    }

    public String getName() {
        return name;
    }

    public LocalDate getDateOfBirth() {
        return dateOfBirth;
    }
    

 public int getAge(){
  return dateOfBirth.until(IsoChronology.INSTANCE.dateNow()).getYears();  
 }

    @Override
    public String toString() {
        return "Person{" + "name=" + name + ", dateOfBirth=" + dateOfBirth + '}';
    }
}


The sample persons are collected from this text file:

Sarah 1999 12 15
Philip 1993 8 12
Beth 1991 6 5
Simon 1990 3 23
Nina 1991 7 12
Allan 1985 2 14
Leonard 1996 10 27
Barbara 1988 4 19

Here is a sample Stream API query to retrieve a comma separated string of the names of the persons in the list, as an additional example of how to retrieve information from an entire collection without using collect, but with map and reduce:

   Optional personNames = persons.stream().map(p->p.getName()).reduce((p1,p2)-> p1 + "," + p2);
            System.out.println(personNames);       

No comments:

Post a Comment