Skip to content

Drozdov Igor streams part3 #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 58 additions & 8 deletions src/test/java/part3/exercise/CollectorCombination.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
import part2.exercise.CollectorsExercise2.Key;
import part2.exercise.CollectorsExercise2.Value;

import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

import static java.util.stream.Collectors.*;
import static org.junit.Assert.assertEquals;

public class CollectorCombination {

Expand All @@ -32,10 +35,50 @@ public B getB() {
}
}

private static <T, M1, M2, R1, R2> Collector<T, Pair<M1, M2>, Pair<R1, R2>> paired(Collector<T, M1, R1> c1,
Collector<T, M2, R2> c2) {
// TODO
throw new UnsupportedOperationException();
private static <T, M1, M2, R1, R2> Collector<T, Pair<M1, M2>, Pair<R1, R2>> paired(
Collector<T, M1, R1> c1,
Collector<T, M2, R2> c2
) {
return new Collector<T, Pair<M1, M2>, Pair<R1, R2>>() {
@Override
public Supplier<Pair<M1, M2>> supplier() {
return () -> new Pair<>(c1.supplier().get(),c2.supplier().get());
}

@Override
public BiConsumer<Pair<M1, M2>, T> accumulator() {
return (pair, t) -> {
c1.accumulator().accept(pair.getA(), t);
c2.accumulator().accept(pair.getB(), t);
};
}

@Override
public BinaryOperator<Pair<M1, M2>> combiner() {
return (p1, p2) ->
new Pair<M1, M2>(
c1.combiner().apply(p1.getA(), p2.getA()),
c2.combiner().apply(p1.getB(), p2.getB())
);
}

@Override
public Function<Pair<M1, M2>, Pair<R1, R2>> finisher() {
return (pair) -> new Pair<R1, R2>(
c1.finisher().apply(pair.getA()),
c2.finisher().apply(pair.getB())
);
}

@Override
public Set<Characteristics> characteristics() {
Set<Characteristics> characteristics = new HashSet<>(c1.characteristics());

characteristics.retainAll(c2.characteristics());

return characteristics;
}
};
}

@Test
Expand All @@ -57,8 +100,15 @@ public void collectKeyValueMap() {
);


// TODO tests
throw new UnsupportedOperationException();
Map<String, Key> collect = pairs.stream()
.collect(mapping(CollectorsExercise2.Pair::getKey, toMap(Key::getId, Function.identity(), (x, y) -> x)));

Map<String, List<Value>> collect1 = pairs.stream()
.collect(mapping(CollectorsExercise2.Pair::getValue, groupingBy(Value::getKeyId)));

assertEquals(res2.getA(), collect);
assertEquals(res2.getB(), collect1);

}

}
33 changes: 16 additions & 17 deletions src/test/java/part3/exercise/lambda/LambdaExercise.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@ public class LambdaExercise {
public void supply() {
final Person person = new Person("John", "Galt", 30);

final Supplier<Person> getPerson = null; // TODO return person from Supplier
final Supplier<Person> getPerson = () -> person;

assertEquals(person, getPerson.get());
}

@Test
public void function() {
final Function<Person, String> getPersonName1 = null; // TODO get the name of person using expression lambda
final Function<Person, String> getPersonName1 = person -> person.getFirstName();

final Function<Person, String> getPersonName2 = null; // TODO get the name of person using method reference
final Function<Person, String> getPersonName2 = Person::getFirstName;

// TODO get the name of person and log it to System.out using statement lambda: {}
final Function<Person, String> getPersonNameAndLogIt = null;
final Function<Person, String> getPersonNameAndLogIt = person -> {
String firstName = person.getFirstName();
System.out.println(firstName);
return firstName;
};

final Person person = new Person("John", "Galt", 30);

Expand All @@ -38,19 +41,17 @@ public void function() {

@Test
public void combineFunctions() {
final Function<Person, String> getPersonName = null; // TODO get the name of person
final Function<Person, String> getPersonName = Person::getFirstName;

assertEquals("John", getPersonName.apply(new Person("John", "Galt", 30)));

final Function<String, Integer> getStringLength = null; // TODO get string length
final Function<String, Integer> getStringLength = String::length;

assertEquals(Integer.valueOf(3), getStringLength.apply("ABC"));

// TODO get person name length using getPersonName and getStringLength without andThen
final Function<Person, Integer> getPersonNameLength1 = null;
final Function<Person, Integer> getPersonNameLength1 = person -> getStringLength.apply(getPersonName.apply(person));

// TODO get person name length using getPersonName and getStringLength with andThen
final Function<Person, Integer> getPersonNameLength2 = null;
final Function<Person, Integer> getPersonNameLength2 = getPersonName.andThen(getStringLength);

final Person person = new Person("John", "Galt", 30);

Expand All @@ -68,22 +69,20 @@ private Person createPerson(PersonFactory pf) {

// ((T -> R), (R -> boolean)) -> (T -> boolean)
private <T, R> Predicate<T> combine(Function<T, R> f, Predicate<R> p) {
// TODO
throw new UnsupportedOperationException();
return t -> p.test(f.apply(t));
}

@Test
public void methodReference() {
// TODO use only method reverences here.
final Person person = createPerson(null); // TODO
final Person person = createPerson(Person::new);

assertEquals(new Person("John", "Galt", 66), person);

final Function<Person, String> getPersonName = null; // TODO
final Function<Person, String> getPersonName = Person::getFirstName;

assertEquals("John", getPersonName.apply(person));

final Predicate<String> isJohnString = null; // TODO using method reference check that "John" equals string parameter
final Predicate<String> isJohnString = "John"::equals;

final Predicate<Person> isJohnPerson = combine(getPersonName, isJohnString);

Expand Down
130 changes: 107 additions & 23 deletions src/test/java/part3/exercise/stream/StreamsExercise.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.Assert.assertEquals;

Expand All @@ -19,7 +19,9 @@ public class StreamsExercise {
public void getAllJobHistoryEntries() {
final List<Employee> employees = getEmployees();

final List<JobHistoryEntry> jobHistoryEntries = null; // TODO
final List<JobHistoryEntry> jobHistoryEntries = employees.stream()
.flatMap(employee -> employee.getJobHistory().stream())
.collect(Collectors.toList());

assertEquals(22, jobHistoryEntries.size());
}
Expand All @@ -29,12 +31,19 @@ public void getSumDuration() {
// sum all durations for all persons
final List<Employee> employees = getEmployees();

final int sumDurations = 0; // TODO
final int sumDurations = employees.stream()
.flatMap(this::toJobHistoryEntry)
.mapToInt(JobHistoryEntry::getDuration)
.sum();

assertEquals(72, sumDurations);
assertEquals(74, sumDurations);
}

private static class PersonEmployer{
private Stream<? extends JobHistoryEntry> toJobHistoryEntry(Employee employee) {
return employee.getJobHistory().stream();
}

private static class PersonEmployer {
private final Person person;
private final String employer;

Expand Down Expand Up @@ -64,16 +73,35 @@ public String toString() {
public void indexPersonsByEmployer1() {
final List<Employee> employees = getEmployees();

final Map<String, List<PersonEmployer>> index = null; // TODO
final Map<String, List<PersonEmployer>> index = employees.stream()
.flatMap(this::toPersonEmployer)
.collect(
Collectors.groupingBy(
PersonEmployer::getEmployer,
Collectors.toList()
)
);

assertEquals(11, index.get("epam").size());
}

private Stream<? extends PersonEmployer> toPersonEmployer(Employee employee) {
return employee.getJobHistory().stream()
.map(jobHistoryEntry -> new PersonEmployer(employee.getPerson(), jobHistoryEntry.getEmployer()));
}

@Test
public void indexPersonsByEmployer2() {
final List<Employee> employees = getEmployees();

final Map<String, List<Person>> index = null; // TODO
final Map<String, List<Person>> index = employees.stream()
.flatMap(this::toPersonEmployer)
.collect(
Collectors.groupingBy(
PersonEmployer::getEmployer,
Collectors.mapping(PersonEmployer::getPerson, Collectors.toList())
)
);

assertEquals(11, index.get("epam").size());
}
Expand Down Expand Up @@ -105,16 +133,24 @@ public String toString() {
}

private PersonDuration sumAllPersonDurations(Employee e) {
// TODO
throw new UnsupportedOperationException();
return new PersonDuration(
e.getPerson(),
e.getJobHistory().stream().mapToInt(JobHistoryEntry::getDuration).sum()
);
}

@Test
public void getSumPersonDuration() {
// sum all durations for each person
final List<Employee> employees = getEmployees();

final Map<Person, Integer> personDuration = null; // TODO use sumAllPersonDurations
final Map<Person, Integer> personDuration = employees.stream()
.map(this::sumAllPersonDurations)
.collect(
Collectors.toMap(
PersonDuration::getPerson,
PersonDuration::getDuration
)
);

assertEquals(Integer.valueOf(8), personDuration.get(new Person("John", "Doe", 24)));
}
Expand All @@ -138,15 +174,23 @@ public Map<String, Integer> getDurationByPositionIndex() {
}

private static PersonPositionIndex getPersonPositionIndex(Employee e) {
// TODO
throw new UnsupportedOperationException();
return new PersonPositionIndex(
e.getPerson(),
e.getJobHistory().stream().collect(Collectors.toMap(
JobHistoryEntry::getPosition,
JobHistoryEntry::getDuration,
(a1, a2) -> a1 + a2
))
);
}

@Test
public void getSumDurationsForPersonByPosition() {
final List<Employee> employees = getEmployees();

final List<PersonPositionIndex> personIndexes = null; // TODO use getPersonPositionIndex
final List<PersonPositionIndex> personIndexes = employees.stream()
.map(StreamsExercise::getPersonPositionIndex)
.collect(Collectors.toList());

assertEquals(1, personIndexes.get(3).getDurationByPositionIndex().size());
}
Expand Down Expand Up @@ -179,18 +223,42 @@ public int getDuration() {
public void getDurationsForEachPersonByPosition() {
final List<Employee> employees = getEmployees();

final List<PersonPositionDuration> personPositionDurations = null; // TODO

final List<PersonPositionDuration> personPositionDurations = employees.stream()
.map(StreamsExercise::getPersonPositionIndex)
.flatMap(
personPositionIndex -> personPositionIndex.getDurationByPositionIndex().entrySet()
.stream()
.map(pair -> new PersonPositionDuration(personPositionIndex.getPerson(), pair.getKey(), pair.getValue()))
)
.collect(Collectors.toList());

assertEquals(17, personPositionDurations.size());
}

private Stream<? extends PersonPositionDuration> toPersonPositionDuration(Employee employee) {
return employee.getJobHistory().stream()
.map(jobHistoryEntry -> new PersonPositionDuration(employee.getPerson(), jobHistoryEntry.getPosition(), jobHistoryEntry.getDuration()));
}

@Test
public void getCoolestPersonByPosition1() {
// Get person with max duration on given position
final List<Employee> employees = getEmployees();

final Map<String, PersonPositionDuration> coolestPersonByPosition = null;// TODO
final Map<String, PersonPositionDuration> coolestPersonByPosition = employees
.stream()
.map(StreamsExercise::getPersonPositionIndex)
.flatMap(
personPositionIndex -> personPositionIndex.getDurationByPositionIndex().entrySet()
.stream()
.map(pair -> new PersonPositionDuration(personPositionIndex.getPerson(), pair.getKey(), pair.getValue()))
)
.collect(
Collectors.toMap(
PersonPositionDuration::getPosition,
Function.identity(),
(p1, p2) -> p1.getDuration() > p2.getDuration() ? p1 : p2
)
);


assertEquals(new Person("John", "White", 22), coolestPersonByPosition.get("QA").getPerson());
Expand All @@ -201,7 +269,23 @@ public void getCoolestPersonByPosition2() {
// Get person with max duration on given position
final List<Employee> employees = getEmployees();

final Map<String, Person> coolestPersonByPosition = null; // TODO
final Map<String, Person> coolestPersonByPosition = employees
.stream()
.map(StreamsExercise::getPersonPositionIndex)
.flatMap(
personPositionIndex -> personPositionIndex.getDurationByPositionIndex().entrySet()
.stream()
.map(pair -> new PersonPositionDuration(personPositionIndex.getPerson(), pair.getKey(), pair.getValue()))
)
.collect(
Collectors.groupingBy(
PersonPositionDuration::getPosition,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparing(PersonPositionDuration::getDuration)),
optional -> optional.get().getPerson()
)
)
);


assertEquals(new Person("John", "White", 22), coolestPersonByPosition.get("QA"));
Expand All @@ -222,7 +306,7 @@ private List<Employee> getEmployees() {
new Employee(
new Person("John", "White", 22),
Collections.singletonList(
new JobHistoryEntry(6, "QA", "epam")
new JobHistoryEntry(8, "QA", "epam")
)),
new Employee(
new Person("John", "Galt", 23),
Expand Down