# GS Collections实例教程（第二部分）

| 作者 Donald Raab 0 他的粉丝 发布于 2015年1月25日. 估计阅读时间: 47 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

GS Collections 实例教程（第一部分）中，我展示了几种运用select和selectWith的方法去筛选一个集合。


@Test
public void doAnyPeopleHaveCats()
{
Predicate predicate = person -> person.hasPet(PetType.CAT);
boolean result =
this.people.anySatisfy(predicate);
Assert.assertTrue(result);

boolean result1 =
this.people.anySatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertTrue(result1);
}




@Test
public void doAllPeopleHaveCats()
{
boolean result =
this.people.allSatisfy(person -> person.hasPet(PetType.CAT));
Assert.assertFalse(result);

boolean result1 =
this.people.allSatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertFalse(result1);
}




@Test
public void doNoPeopleHaveCats()
{
boolean result =
this.people.noneSatisfy(person -> person.hasPet(PetType.CAT));
Assert.assertFalse(result);

boolean result1 =
this.people.noneSatisfyWith(Person::hasPet, PetType.CAT);
Assert.assertFalse(result1);
}




@Test
public void howManyPeopleHaveCats()
{
int count =
this.people.count(person -> person.hasPet(PetType.CAT));
Assert.assertEquals(2, count);

int count1 =
this.people.countWith(Person::hasPet, PetType.CAT);
Assert.assertEquals(2, count1);
}




@Test
public void findPersonNamedMarySmith()
{
Person result =
this.people.detect(person -> person.named("Mary Smith"));
Assert.assertEquals("Mary", result.getFirstName());
Assert.assertEquals("Smith", result.getLastName());

Person result1 =
this.people.detectWith(Person::named, "Mary Smith");
Assert.assertEquals("Mary", result1.getFirstName());
Assert.assertEquals("Smith", result1.getLastName());
} 

any、all、noneSatisfy以及detect都是短路求值方法的例子，它们可以不用遍历每一个集合里的元素就可返回结果。比如说，anySatisfy就像逻辑中的“”，只要找到一个满足条件的元素它就会判断为是，否则将检视整个集合而判断为否。


@Test
public void getPeopleWithCats()
{
MutableList peopleWithCats =
this.people.select(person -> person.hasPet(PetType.CAT))
Verify.assertSize(2, peopleWithCats);

MutableList peopleWithCats1 =
this.people.selectWith(Person::hasPet, PetType.CAT);
Verify.assertSize(2, peopleWithCats1);
}


@Test
public void getPeopleWhoDontHaveCats()
{
MutableList peopleWithNoCats =
this.people.reject(person -> person.hasPet(PetType.CAT));
Verify.assertSize(5, peopleWithNoCats);

MutableList peopleWithNoCats1 =
this.people.rejectWith(Person::hasPet, PetType.CAT);
Verify.assertSize(5, peopleWithNoCats1);
}


@Test
public void partitionPeopleByCatOwnersAndNonCatOwners()
{
PartitionMutableList catsAndNoCats =
this.people.partition(person -> person.hasPet(PetType.CAT));
Verify.assertSize(2, catsAndNoCats.getSelected());
Verify.assertSize(5, catsAndNoCats.getRejected());

PartitionMutableList catsAndNoCats1 =
this.people.partitionWith(Person::hasPet, PetType.CAT);
Verify.assertSize(2, catsAndNoCats1.getSelected());
Verify.assertSize(5, catsAndNoCats1.getRejected());
}


@Test
public void getTheNamesOfBobSmithPets()
{
Person person =
this.people.detectWith(Person::named, "Bob Smith");
MutableList pets = person.getPets();
MutableList names =
pets.collect(Pet::getName);
Assert.assertEquals("Dolly, Spot", names.makeString());
}


@Test
public void getAllPets()
{
Function<Person, Iterable<PetType>> function = person ->
person.getPetTypes();
Assert.assertEquals(
UnifiedSet.newSetWith(PetType.values()),
this.people.flatCollect(function).toSet()
);
Assert.assertEquals(
UnifiedSet.newSetWith(PetType.values()),
this.people.flatCollect(Person::getPetTypes).toSet()
);
}


@Test
public void groupPeopleByLastName()
{
Multimap<String, Person> byLastName =
this.people.groupBy(Person::getLastName);
Verify.assertIterableSize(3, byLastName.get("Smith"));
}


@Test
public void groupPeopleByTheirPets()
{
Multimap<PetType, Person> peopleByPets =
this.people.groupByEach(Person::getPetTypes);
RichIterable<Person> catPeople = peopleByPets.get(PetType.CAT);
Assert.assertEquals(
"Mary, Bob",
catPeople.collect(Person::getFirstName).makeString()
);
RichIterable<Person> dogPeople = peopleByPets.get(PetType.DOG);
Assert.assertEquals(
"Bob, Ted",
dogPeople.collect(Person::getFirstName).makeString()
);
}


@Test
public void getTotalNumberOfPets()
{
long numberOfPets = this.people.sumOfInt(Person::getNumberOfPets);
Assert.assertEquals(9, numberOfPets);
}



public interface IntFunction<T>
extends Serializable
{
int intValueOf(T anObject);
}


GS Collections里所有的Procedures，Functions，Predicates 都继承了Serializable。这样一来，程序员不用编写自己的Serializable扩展就可以安全地序列化到磁盘上或是远程传递。


@Test
public void getAgesOfPets()
{
IntList sortedAges =
this.people
.asLazy()
.flatCollect(Person::getPets)
.collectInt(Pet::getAge)
.toSortedList();
IntSet uniqueAges = sortedAges.toSet();
IntSummaryStatistics stats = new IntSummaryStatistics();
sortedAges.forEach(stats::accept);
Assert.assertTrue(sortedAges.allSatisfy(IntPredicates.greaterThan(0)));
Assert.assertTrue(sortedAges.allSatisfy(i -> i > 0));
Assert.assertFalse(sortedAges.anySatisfy(i -> i == 0));
Assert.assertTrue(sortedAges.noneSatisfy(i -> i < 0));
Assert.assertEquals(IntHashSet.newSetWith(1, 2, 3, 4), uniqueAges);
Assert.assertEquals(2.0d, sortedAges.median(), 0.0);
Assert.assertEquals(stats.getMin(), sortedAges.min());
Assert.assertEquals(stats.getMax(), sortedAges.max());
Assert.assertEquals(stats.getSum(), sortedAges.sum());
Assert.assertEquals(stats.getAverage(), sortedAges.average(), 0.0);
Assert.assertEquals(stats.getCount(), sortedAges.size());
}



@Test
public void getCountsByPetType()
{
Bag<PetType> counts =
this.people
.asLazy()
.flatCollect(Person::getPets)
.collect(Pet::getType)
.toBag();
Assert.assertEquals(2, counts.occurrencesOf(PetType.CAT));
Assert.assertEquals(2, counts.occurrencesOf(PetType.DOG));
Assert.assertEquals(2, counts.occurrencesOf(PetType.HAMSTER));
Assert.assertEquals(1, counts.occurrencesOf(PetType.SNAKE));
Assert.assertEquals(1, counts.occurrencesOf(PetType.TURTLE));
Assert.assertEquals(1, counts.occurrencesOf(PetType.BIRD));
}




@Test
public void getCountsByPetAge()
{
IntBag counts =
this.people
.asLazy()
.flatCollect(Person::getPets)
.collectInt(Pet::getAge)
.toBag();
Assert.assertEquals(4, counts.occurrencesOf(1));
Assert.assertEquals(3, counts.occurrencesOf(2));
Assert.assertEquals(1, counts.occurrencesOf(3));
Assert.assertEquals(1, counts.occurrencesOf(4));
Assert.assertEquals(0, counts.occurrencesOf(5));
}




import com.gs.collections.api.RichIterable;
import com.gs.collections.api.bag.Bag;
import com.gs.collections.api.bag.MutableBag;
import com.gs.collections.api.bag.primitive.IntBag;
import com.gs.collections.api.block.function.Function;
import com.gs.collections.api.block.predicate.Predicate;
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.partition.list.PartitionMutableList;
import com.gs.collections.api.set.primitive.IntSet;
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.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 org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.IntSummaryStatistics;

public class PersonTest
{
MutableList<Person> people;

@Before
public void setUp() throws Exception
{
this.people = FastList.newListWith(
1)
);
}

public class Person
{
private String firstName;
private String lastName;
private 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.getFirstName() + " " +
this.getLastName());
}

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)
{
return this;
}

public int getNumberOfPets()
{
return this.pets.size();
}
}

public class Pet
{
private PetType type;
private String name;
private 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
}
}



## 关于作者

Donald Raab在高盛的信息技术部领导JVM Architecture 小组，该小组隶属于Enterprise Platforms团队。Raab是JSR 335专家组（Java编程语言的Lambda Expressions）的成员,并且是高盛在JCP（Java Community Process）执行委员会的代表之一。他于2001年作为技术架构师加入高盛信息技术部的会计&风险分析组。他在2007年被授予高盛的Technology Fellow头衔，并在2013年成为董事总经理。