package ch.claude_martin; import java.security.SecureRandom; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.stream.Collectors; public class SomeClass { /** This is the data bean. It's a plain old java object. */ public static class Bike { private String modelName; private LocalDate purchaseDate; private String contact; private int price; public String getModelName() { return modelName; } public void setModelName(String modelName) { this.modelName = modelName; } public LocalDate getPurchaseDate() { return purchaseDate; } public void setPurchaseDate(LocalDate purchaseDate) { this.purchaseDate = purchaseDate; } public String getContact() { return contact; } public void setContact(String contact) { this.contact = contact; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { return String.format("Bike(%s, %s, %d, %s)", modelName, purchaseDate, price, contact); } } /** * This is just a simple pair, but Java doesn't have a type for this. You could * use Map.Entry for this. For a group over 3 fields you need a three-tuple * instead. */ public static class Pair { private A a; private B b; public Pair(A a, B b) { super(); this.a = a; this.b = b; } @Override public int hashCode() { return a.hashCode() + b.hashCode() * 31; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Pair other = (Pair) obj; return this.a.equals(other.a) && this.b.equals(other.b); } @Override public String toString() { return String.format("Group(%s, %s)", a, b); } } public static void main(String[] args) { final List bikes = new ArrayList<>(); final List contacts = List.of("Bob", "Jill", "Jack", "Susie", "Burt", "Emma"); final Random rng = new SecureRandom(); for (int month = 1; month < 13; month++) { for (int day = 1; day < 29; day++) { for (int i = 0; i < rng.nextInt(4); i++) { for (String contact : contacts) { Bike b = new Bike(); b.setContact(contact); b.setPurchaseDate(LocalDate.of(2018, month, day)); b.setPrice(rng.nextInt(5000) + 500); b.setModelName(Long.toString(Math.abs(rng.nextLong() % 3656158440062976L), 36)); bikes.add(b); } } } } System.out.println("Database is ready"); Map, List> groups = bikes.stream() .collect(Collectors.groupingBy(b -> new Pair<>(b.getContact(), b.getPurchaseDate()))); for (Entry, List> entry : groups.entrySet()) { System.out.println("====="); System.out.print(entry.getKey()); System.out.print(": "); System.out.println(entry.getValue()); } System.out.println("====="); System.out.println("THE END"); } }