/*
* Copyright 2015 Goldman Sachs.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gs.collections.impl;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.gs.collections.api.RichIterable;
import com.gs.collections.api.bag.ImmutableBag;
import com.gs.collections.api.bag.MutableBag;
import com.gs.collections.api.bag.primitive.ImmutableIntBag;
import com.gs.collections.api.list.MutableList;
import com.gs.collections.api.list.primitive.IntList;
import com.gs.collections.api.multimap.Multimap;
import com.gs.collections.api.multimap.bag.MutableBagMultimap;
import com.gs.collections.api.multimap.list.MutableListMultimap;
import com.gs.collections.api.partition.PartitionIterable;
import com.gs.collections.api.partition.list.PartitionMutableList;
import com.gs.collections.api.set.MutableSet;
import com.gs.collections.api.set.primitive.IntSet;
import com.gs.collections.api.tuple.primitive.ObjectIntPair;
import com.gs.collections.impl.bag.mutable.HashBag;
import com.gs.collections.impl.block.factory.Predicates2;
import com.gs.collections.impl.block.factory.primitive.IntPredicates;
import com.gs.collections.impl.factory.Bags;
import com.gs.collections.impl.factory.Lists;
import com.gs.collections.impl.factory.Multimaps;
import com.gs.collections.impl.factory.Sets;
import com.gs.collections.impl.list.mutable.FastList;
import com.gs.collections.impl.set.mutable.UnifiedSet;
import com.gs.collections.impl.set.mutable.primitive.IntHashSet;
import com.gs.collections.impl.test.Verify;
import com.gs.collections.impl.tuple.primitive.PrimitiveTuples;
import com.gs.collections.impl.utility.StringIterate;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class PersonAndPetKataTest
{
private MutableList<Person> people;
@Before
public void setUp() throws Exception
{
this.people = Lists.mutable.with(
new Person("Mary", "Smith").addPet(PetType.CAT, "Tabby", 2),
new Person("Bob", "Smith")
.addPet(PetType.CAT, "Dolly", 3)
.addPet(PetType.DOG, "Spot", 2),
new Person("Ted", "Smith").addPet(PetType.DOG, "Spike", 4),
new Person("Jake", "Snake").addPet(PetType.SNAKE, "Serpy", 1),
new Person("Barry", "Bird").addPet(PetType.BIRD, "Tweety", 2),
new Person("Terry", "Turtle").addPet(PetType.TURTLE, "Speedy", 1),
new Person("Harry", "Hamster")
.addPet(PetType.HAMSTER, "Fuzzy", 1)
.addPet(PetType.HAMSTER, "Wuzzy", 1)
);
}
@Test
public void doAnyPeopleHaveCats()
{
boolean resultEager =
this.people.anySatisfy(person -> person.hasPet(PetType.CAT));
Assert.assertTrue(resultEager);
boolean resultEagerMR =
this.people.anySatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertTrue(resultEagerMR);
boolean resultLazy =
this.people.asLazy().anySatisfy(person -> person.hasPet(PetType.CAT));
Assert.assertTrue(resultLazy);
boolean resultLazyMR =
this.people.asLazy().anySatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertTrue(resultLazyMR);
}
@Test
public void doAnyPeopleHaveCatsUsingStreams()
{
boolean result =
this.people.stream().anyMatch(person -> person.hasPet(PetType.CAT));
Assert.assertTrue(result);
}
@Test
public void doAllPeopleHaveCats()
{
boolean resultEager =
this.people.allSatisfy(person -> person.hasPet(PetType.CAT));
Assert.assertFalse(resultEager);
boolean resultEagerMR =
this.people.allSatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertFalse(resultEagerMR);
boolean resultLazy =
this.people.allSatisfy(person -> person.hasPet(PetType.CAT));
Assert.assertFalse(resultLazy);
boolean resultLazyMR =
this.people.allSatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertFalse(resultLazyMR);
}
@Test
public void doAllPeopleHaveCatsUsingStreams()
{
boolean resultStream =
this.people.stream().allMatch(person -> person.hasPet(PetType.CAT));
Assert.assertFalse(resultStream);
}
@Test
public void doNoPeopleHaveCats()
{
boolean resultEager =
this.people.noneSatisfy(person -> person.hasPet(PetType.CAT));
Assert.assertFalse(resultEager);
boolean resultEagerMR =
this.people.noneSatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertFalse(resultEagerMR);
boolean resultLazy =
this.people.asLazy().noneSatisfy(person -> person.hasPet(PetType.CAT));
Assert.assertFalse(resultLazy);
boolean resultLazyMR =
this.people.asLazy().noneSatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertFalse(resultLazyMR);
}
@Test
public void doNoPeopleHaveCatsUsingStreams()
{
boolean resultStream =
this.people.stream().noneMatch(person -> person.hasPet(PetType.CAT));
Assert.assertFalse(resultStream);
}
@Test
public void howManyPeopleHaveCats()
{
int countEager =
this.people.count(person -> person.hasPet(PetType.CAT));
Assert.assertEquals(2, countEager);
int countEagerMR =
this.people.countWith(Person::hasPet, PetType.CAT);
Assert.assertEquals(2, countEagerMR);
int countLazy =
this.people.asLazy().count(person -> person.hasPet(PetType.CAT));
Assert.assertEquals(2, countLazy);
int countLazyMR =
this.people.asLazy().countWith(Person::hasPet, PetType.CAT);
Assert.assertEquals(2, countLazyMR);
}
@Test
public void howManyPeopleHaveCatsUsingStreams()
{
long countStream =
this.people.stream().filter(person -> person.hasPet(PetType.CAT)).count();
Assert.assertEquals(2, countStream);
}
@Test
public void getPeopleWithCats()
{
MutableList<Person> peopleWithCatsEager =
this.people.select(person ->
person.hasPet(PetType.CAT));
Verify.assertSize(2, peopleWithCatsEager);
MutableList<Person> peopleWithCatsEagerMR =
this.people.selectWith(Person::hasPet, PetType.CAT);
Verify.assertSize(2, peopleWithCatsEagerMR);
MutableList<Person> peopleWithCatsLazy =
this.people.asLazy().select(person -> person.hasPet(PetType.CAT)).toList();
Verify.assertSize(2, peopleWithCatsLazy);
MutableList<Person> peopleWithCatsLazyMR =
this.people.asLazy().selectWith(Person::hasPet, PetType.CAT).toList();
Verify.assertSize(2, peopleWithCatsLazyMR);
}
@Test
public void getPeopleWithCatsUsingStreams()
{
List<Person> peopleWithCatsStream =
this.people.stream().filter(person -> person.hasPet(PetType.CAT)).collect(Collectors.toList());
Verify.assertSize(2, peopleWithCatsStream);
}
@Test
public void getPeopleWhoDontHaveCats()
{
MutableList<Person> peopleWithNoCatsEager =
this.people.reject(person -> person.hasPet(PetType.CAT));
Verify.assertSize(5, peopleWithNoCatsEager);
MutableList<Person> peopleWithNoCatsEagerMR =
this.people.rejectWith(Person::hasPet, PetType.CAT);
Verify.assertSize(5, peopleWithNoCatsEagerMR);
MutableList<Person> peopleWithNoCatsLazy =
this.people.reject(person -> person.hasPet(PetType.CAT));
Verify.assertSize(5, peopleWithNoCatsLazy);
MutableList<Person> peopleWithNoCatsLazyMR =
this.people.rejectWith(Person::hasPet, PetType.CAT);
Verify.assertSize(5, peopleWithNoCatsLazyMR);
}
@Test
public void getPeopleWhoDontHaveCatsUsingStreams()
{
List<Person> peopleWithNoCatsStream =
this.people.stream().filter(person -> !person.hasPet(PetType.CAT)).collect(Collectors.toList());
Verify.assertSize(5, peopleWithNoCatsStream);
}
@Test
public void partitionPeopleByCatOwnersAndNonCatOwners()
{
PartitionMutableList<Person> catsAndNoCatsEager =
this.people.partition(person ->
person.hasPet(PetType.CAT));
Verify.assertSize(2, catsAndNoCatsEager.getSelected());
Verify.assertSize(5, catsAndNoCatsEager.getRejected());
PartitionMutableList<Person> catsAndNoCatsEagerMR =
this.people.partitionWith(Person::hasPet, PetType.CAT);
Verify.assertSize(2, catsAndNoCatsEagerMR.getSelected());
Verify.assertSize(5, catsAndNoCatsEagerMR.getRejected());
PartitionIterable<Person> catsAndNoCatsLazy =
this.people.asLazy().partition(person ->
person.hasPet(PetType.CAT));
Verify.assertSize(2, catsAndNoCatsLazy.getSelected());
Verify.assertSize(5, catsAndNoCatsLazy.getRejected());
PartitionIterable<Person> catsAndNoCatsLazyMR =
this.people.asLazy().partitionWith(Person::hasPet, PetType.CAT);
Verify.assertSize(2, catsAndNoCatsLazyMR.getSelected());
Verify.assertSize(5, catsAndNoCatsLazyMR.getRejected());
}
@Test
public void partitionPeopleByCatOwnersAndNonCatOwnersUsingStreams()
{
Map<Boolean, List<Person>> catsAndNoCatsStream =
this.people.stream().collect(Collectors.partitioningBy(person ->
person.hasPet(PetType.CAT)));
Verify.assertSize(2, catsAndNoCatsStream.get(true));
Verify.assertSize(5, catsAndNoCatsStream.get(false));
}
@Test
public void findPersonNamedMarySmith()
{
Person resultEager =
this.people.detect(person -> person.named("Mary Smith"));
Assert.assertEquals("Mary", resultEager.getFirstName());
Assert.assertEquals("Smith", resultEager.getLastName());
Person resultEagerMR =
this.people.detectWith(Person::named, "Mary Smith");
Assert.assertEquals("Mary", resultEagerMR.getFirstName());
Assert.assertEquals("Smith", resultEagerMR.getLastName());
Person resultLazy =
this.people.asLazy().detect(person -> person.named("Mary Smith"));
Assert.assertEquals("Mary", resultLazy.getFirstName());
Assert.assertEquals("Smith", resultLazy.getLastName());
Person resultLazyMR =
this.people.asLazy().detectWith(Person::named, "Mary Smith");
Assert.assertEquals("Mary", resultLazyMR.getFirstName());
Assert.assertEquals("Smith", resultLazyMR.getLastName());
}
@Test
public void findPersonNamedMarySmithUsingStreams()
{
Person resultStream =
this.people.stream().filter(person -> person.named("Mary Smith")).findFirst().get();
Assert.assertEquals("Mary", resultStream.getFirstName());
Assert.assertEquals("Smith", resultStream.getLastName());
}
@Test
public void getTheNamesOfBobSmithPets()
{
Person personEager =
this.people.detectWith(Person::named, "Bob Smith");
MutableList<String> names =
personEager.getPets().collect(Pet::getName);
Assert.assertEquals(Lists.mutable.with("Dolly", "Spot"), names);
Assert.assertEquals("Dolly & Spot",
names.makeString(" & "));
}
@Test
public void getTheNamesOfBobSmithPetsUsingStreams()
{
Person personStream =
this.people.stream()
.filter(each -> each.named("Bob Smith"))
.findFirst().get();
List<String> names =
personStream.getPets().stream()
.map(Pet::getName)
.collect(Collectors.toList());
Assert.assertEquals(Lists.mutable.with("Dolly", "Spot"), names);
Assert.assertEquals("Dolly & Spot",
names.stream().collect(Collectors.joining(" & ")));
}
@Test
public void getAllPetTypes()
{
MutableSet<PetType> allPetTypesEager =
this.people.flatCollect(Person::getPetTypes).toSet();
Assert.assertEquals(
UnifiedSet.newSetWith(PetType.values()),
allPetTypesEager
);
MutableSet<PetType> allPetTypesEagerTarget =
this.people.flatCollect(Person::getPetTypes, Sets.mutable.empty());
Assert.assertEquals(
UnifiedSet.newSetWith(PetType.values()),
allPetTypesEagerTarget
);
MutableSet<PetType> allPetTypesLazy =
this.people.asLazy().flatCollect(Person::getPetTypes).toSet();
Assert.assertEquals(
UnifiedSet.newSetWith(PetType.values()),
allPetTypesLazy
);
MutableSet<PetType> allPetTypesLazyTarget =
this.people.asLazy().flatCollect(Person::getPetTypes, Sets.mutable.empty());
Assert.assertEquals(
UnifiedSet.newSetWith(PetType.values()),
allPetTypesLazyTarget
);
}
@Test
public void getAllPetTypesUsingStreams()
{
Set<PetType> allPetTypesStream =
this.people.stream()
.flatMap(person -> person.getPetTypes().stream())
.collect(Collectors.toSet());
Assert.assertEquals(
new HashSet<>(Arrays.asList(PetType.values())),
allPetTypesStream
);
}
@Test
public void groupPeopleByLastName()
{
MutableListMultimap<String, Person> byLastNameEager =
this.people.groupBy(Person::getLastName);
Verify.assertIterableSize(3, byLastNameEager.get("Smith"));
MutableBagMultimap<String, Person> byLastNameEagerTargetBag =
this.people.groupBy(Person::getLastName, Multimaps.mutable.bag.empty());
Verify.assertIterableSize(3, byLastNameEagerTargetBag.get("Smith"));
Multimap<String, Person> byLastNameLazy =
this.people.asLazy().groupBy(Person::getLastName);
Verify.assertIterableSize(3, byLastNameLazy.get("Smith"));
MutableBagMultimap<String, Person> byLastNameLazyTargetBag =
this.people.asLazy().groupBy(Person::getLastName, Multimaps.mutable.bag.empty());
Verify.assertIterableSize(3, byLastNameLazyTargetBag.get("Smith"));
}
@Test
public void groupPeopleByLastNameUsingStreams()
{
Map<String, List<Person>> byLastNameStream =
this.people.stream().collect(
Collectors.groupingBy(Person::getLastName));
Verify.assertIterableSize(3, byLastNameStream.get("Smith"));
Map<String, MutableBag<Person>> byLastNameStreamTargetBag =
this.people.stream().collect(
Collectors.groupingBy(Person::getLastName, Collectors.toCollection(Bags.mutable::empty)));
Verify.assertIterableSize(3, byLastNameStreamTargetBag.get("Smith"));
}
@Test
public void groupPeopleByTheirPets()
{
Multimap<PetType, Person> peopleByPetsEager =
this.people.groupByEach(Person::getPetTypes);
RichIterable<Person> catPeople = peopleByPetsEager.get(PetType.CAT);
Assert.assertEquals(
"Mary, Bob",
catPeople.collect(Person::getFirstName).makeString()
);
RichIterable<Person> dogPeople = peopleByPetsEager.get(PetType.DOG);
Assert.assertEquals(
"Bob, Ted",
dogPeople.collect(Person::getFirstName).makeString()
);
}
@Test
public void groupPeopleByTheirPetsUsingStreams()
{
Map<PetType, List<Person>> peopleByPetsStream = new HashMap<>();
this.people.stream().forEach(
person -> person.getPetTypes().stream().forEach(
petType -> peopleByPetsStream.computeIfAbsent(petType, e -> new ArrayList<>()).add(person)));
List<Person> catPeople = peopleByPetsStream.get(PetType.CAT);
Assert.assertEquals(
"Mary, Bob",
catPeople.stream().map(Person::getFirstName).collect(Collectors.joining(", "))
);
List<Person> dogPeople = peopleByPetsStream.get(PetType.DOG);
Assert.assertEquals(
"Bob, Ted",
dogPeople.stream().map(Person::getFirstName).collect(Collectors.joining(", "))
);
}
@Test
public void getTotalNumberOfPets()
{
long numberOfPetsEager = this.people.sumOfInt(Person::getNumberOfPets);
Assert.assertEquals(9, numberOfPetsEager);
long numberOfPetsLazy = this.people.asLazy().sumOfInt(Person::getNumberOfPets);
Assert.assertEquals(9, numberOfPetsLazy);
}
@Test
public void getTotalNumberOfPetsUsingStreams()
{
int numberOfPetsStream = this.people.stream().mapToInt(Person::getNumberOfPets).sum();
Assert.assertEquals(9, numberOfPetsStream);
}
@Test
public void testStrings()
{
Assert.assertEquals("HELLO",
"h1e2l3l4o"
.chars()
.filter(Character::isLetter)
.map(Character::toUpperCase)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, null).toString());
Assert.assertEquals("HELLO",
"h1e2l3l4o"
.codePoints()
.filter(Character::isLetter)
.map(Character::toUpperCase)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, null).toString());
Assert.assertEquals("HELLO",
StringIterate.asCharAdapter("h1e2l3l4o")
.select(Character::isLetter)
.collectChar(Character::toUpperCase)
.toString());
Assert.assertEquals("HELLO",
StringIterate.asCodePointAdapter("h1e2l3l4o")
.select(Character::isLetter)
.collectInt(Character::toUpperCase)
.toString());
}
@Test
public void getAgeStatisticsOfPets()
{
IntList agesLazy = this.people.asLazy()
.flatCollect(Person::getPets)
.collectInt(Pet::getAge)
.toList();
IntSet uniqueAges = agesLazy.toSet();
IntSummaryStatistics stats = new IntSummaryStatistics();
agesLazy.forEach(stats::accept);
Assert.assertEquals(IntHashSet.newSetWith(1, 2, 3, 4), uniqueAges);
Assert.assertEquals(stats.getMin(), agesLazy.min());
Assert.assertEquals(stats.getMax(), agesLazy.max());
Assert.assertEquals(stats.getSum(), agesLazy.sum());
Assert.assertEquals(stats.getAverage(), agesLazy.average(), 0.0);
Assert.assertEquals(stats.getCount(), agesLazy.size());
Assert.assertTrue(agesLazy.allSatisfy(IntPredicates.greaterThan(0)));
Assert.assertTrue(agesLazy.allSatisfy(i -> i > 0));
Assert.assertFalse(agesLazy.anySatisfy(i -> i == 0));
Assert.assertTrue(agesLazy.noneSatisfy(i -> i < 0));
Assert.assertEquals(2.0d, agesLazy.median(), 0.0);
}
@Test
public void getAgeStatisticsOfPetsUsingStreams()
{
List<Integer> agesStream = this.people.stream()
.flatMap(person -> person.getPets().stream())
.map(Pet::getAge)
.collect(Collectors.toList());
Set<Integer> uniqueAges = new HashSet<>(agesStream);
IntSummaryStatistics stats = agesStream.stream().collect(
Collectors.summarizingInt(i -> i));
Assert.assertEquals(Sets.mutable.with(1, 2, 3, 4), uniqueAges);
Assert.assertEquals(stats.getMin(), agesStream.stream().mapToInt(i -> i).min().getAsInt());
Assert.assertEquals(stats.getMax(), agesStream.stream().mapToInt(i -> i).max().getAsInt());
Assert.assertEquals(stats.getSum(), agesStream.stream().mapToInt(i -> i).sum());
Assert.assertEquals(stats.getAverage(), agesStream.stream().mapToInt(i -> i).average().getAsDouble(), 0.0);
Assert.assertEquals(stats.getCount(), agesStream.size());
Assert.assertTrue(agesStream.stream().allMatch(i -> i > 0));
Assert.assertFalse(agesStream.stream().anyMatch(i -> i == 0));
Assert.assertTrue(agesStream.stream().noneMatch(i -> i < 0));
}
@Test
public void getCountsByPetType()
{
ImmutableBag<PetType> countsLazy =
this.people.asLazy()
.flatCollect(Person::getPets)
.collect(Pet::getType)
.toBag()
.toImmutable();
Assert.assertEquals(2, countsLazy.occurrencesOf(PetType.CAT));
Assert.assertEquals(2, countsLazy.occurrencesOf(PetType.DOG));
Assert.assertEquals(2, countsLazy.occurrencesOf(PetType.HAMSTER));
Assert.assertEquals(1, countsLazy.occurrencesOf(PetType.SNAKE));
Assert.assertEquals(1, countsLazy.occurrencesOf(PetType.TURTLE));
Assert.assertEquals(1, countsLazy.occurrencesOf(PetType.BIRD));
}
@Test
public void getCountsByPetTypeUsingStreams()
{
Map<PetType, Long> countsStream =
Collections.unmodifiableMap(
this.people.stream()
.flatMap(person -> person.getPets().stream())
.collect(Collectors.groupingBy(Pet::getType,
Collectors.counting())));
Assert.assertEquals(Long.valueOf(2L), countsStream.get(PetType.CAT));
Assert.assertEquals(Long.valueOf(2L), countsStream.get(PetType.DOG));
Assert.assertEquals(Long.valueOf(2L), countsStream.get(PetType.HAMSTER));
Assert.assertEquals(Long.valueOf(1L), countsStream.get(PetType.SNAKE));
Assert.assertEquals(Long.valueOf(1L), countsStream.get(PetType.TURTLE));
Assert.assertEquals(Long.valueOf(1L), countsStream.get(PetType.BIRD));
}
@Test
public void getTop3Pets()
{
MutableList<ObjectIntPair<PetType>> favoritesLazy =
this.people.asLazy()
.flatCollect(Person::getPets)
.collect(Pet::getType)
.toBag()
.topOccurrences(3);
Verify.assertSize(3, favoritesLazy);
Verify.assertContains(PrimitiveTuples.pair(PetType.CAT, 2), favoritesLazy);
Verify.assertContains(PrimitiveTuples.pair(PetType.DOG, 2), favoritesLazy);
Verify.assertContains(PrimitiveTuples.pair(PetType.HAMSTER, 2), favoritesLazy);
}
@Test
public void getTop3PetsUsingStreams()
{
List<Map.Entry<PetType, Long>> favoritesStream =
this.people.stream()
.flatMap(p -> p.getPets().stream())
.collect(Collectors.groupingBy(Pet::getType, Collectors.counting()))
.entrySet()
.stream()
.sorted(Comparator.comparingLong(e -> -e.getValue()))
.limit(3)
.collect(Collectors.toList());
Verify.assertSize(3, favoritesStream);
Verify.assertContains(new AbstractMap.SimpleEntry<>(PetType.CAT, Long.valueOf(2)), favoritesStream);
Verify.assertContains(new AbstractMap.SimpleEntry<>(PetType.DOG, Long.valueOf(2)), favoritesStream);
Verify.assertContains(new AbstractMap.SimpleEntry<>(PetType.HAMSTER, Long.valueOf(2)), favoritesStream);
}
@Test
public void getBottom3Pets()
{
MutableList<ObjectIntPair<PetType>> leastFavoritesLazy =
this.people
.asLazy()
.flatCollect(Person::getPets)
.collect(Pet::getType)
.toBag()
.bottomOccurrences(3);
Verify.assertSize(3, leastFavoritesLazy);
Verify.assertContains(PrimitiveTuples.pair(PetType.SNAKE, 1), leastFavoritesLazy);
Verify.assertContains(PrimitiveTuples.pair(PetType.TURTLE, 1), leastFavoritesLazy);
Verify.assertContains(PrimitiveTuples.pair(PetType.BIRD, 1), leastFavoritesLazy);
}
@Test
public void getCountsByPetAge()
{
ImmutableIntBag countsLazy =
this.people.asLazy()
.flatCollect(Person::getPets)
.collectInt(Pet::getAge)
.toBag()
.toImmutable();
Assert.assertEquals(4, countsLazy.occurrencesOf(1));
Assert.assertEquals(3, countsLazy.occurrencesOf(2));
Assert.assertEquals(1, countsLazy.occurrencesOf(3));
Assert.assertEquals(1, countsLazy.occurrencesOf(4));
Assert.assertEquals(0, countsLazy.occurrencesOf(5));
}
@Test
public void getCountsByPetAgeUsingStreams()
{
Map<Integer, Long> countsStream =
Collections.unmodifiableMap(
this.people.stream()
.flatMap(person -> person.getPets().stream())
.collect(Collectors.groupingBy(Pet::getAge,
Collectors.counting())));
Assert.assertEquals(Long.valueOf(4), countsStream.get(1));
Assert.assertEquals(Long.valueOf(3), countsStream.get(2));
Assert.assertEquals(Long.valueOf(1), countsStream.get(3));
Assert.assertEquals(Long.valueOf(1), countsStream.get(4));
Assert.assertNull(countsStream.get(5));
}
public static final class Person
{
private final String firstName;
private final String lastName;
private final MutableList<Pet> pets = FastList.newList();
private Person(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName()
{
return this.firstName;
}
public String getLastName()
{
return this.lastName;
}
public boolean named(String name)
{
return name.equals(this.firstName + ' ' + this.lastName);
}
public boolean hasPet(PetType petType)
{
return this.pets.anySatisfyWith(Predicates2.attributeEqual(Pet::getType), petType);
}
public MutableList<Pet> getPets()
{
return this.pets;
}
public MutableBag<PetType> getPetTypes()
{
return this.pets.collect(Pet::getType, HashBag.newBag());
}
public Person addPet(PetType petType, String name, int age)
{
this.pets.add(new Pet(petType, name, age));
return this;
}
public int getNumberOfPets()
{
return this.pets.size();
}
}
public static class Pet
{
private final PetType type;
private final String name;
private final int age;
public Pet(PetType type, String name, int age)
{
this.type = type;
this.name = name;
this.age = age;
}
public PetType getType()
{
return this.type;
}
public String getName()
{
return this.name;
}
public int getAge()
{
return this.age;
}
}
public enum PetType
{
CAT, DOG, HAMSTER, TURTLE, BIRD, SNAKE
}
}