Skip to content

Drozdov Igor stream part2 #70

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 3 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
93 changes: 75 additions & 18 deletions src/test/java/part2/exercise/CollectorsExercise1.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@
import org.junit.Test;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
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 java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

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

public class CollectorsExercise1 {

Expand Down Expand Up @@ -53,16 +49,41 @@ public int getDuration() {

// With the longest duration on single job
private Map<String, Person> getCoolestByPosition(List<Employee> employees) {
// First option
// Collectors.maxBy
// Collectors.collectingAndThen
// Collectors.groupingBy

// Second option
// Collectors.toMap
// iterate twice: stream...collect(...).stream()...
// TODO
throw new UnsupportedOperationException();
Map<String, Person> collect = employees.stream()
.flatMap(
this::toPersonPositionDuration
)
.collect(
groupingBy(
PersonPositionDuration::getPosition,
collectingAndThen(maxBy(Comparator.comparing(PersonPositionDuration::getDuration)), p -> p.get().getPerson())
)
);

Map<String, Person> collect1 = employees.stream()
.flatMap(this::toPersonPositionDuration)
.collect(Collectors.toMap(
PersonPositionDuration::getPosition,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(PersonPositionDuration::getDuration))
))
.entrySet().stream()
.collect(
toMap(
Map.Entry::getKey,
t -> t.getValue().getPerson()
)
);


assertEquals(collect, collect);

return collect;
}

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

@Test
Expand All @@ -75,8 +96,44 @@ public void getTheCoolestOne2() {
// With the longest sum duration on this position
// { John Doe, [{dev, google, 4}, {dev, epam, 4}] } предпочтительнее, чем { A B, [{dev, google, 6}, {QA, epam, 100}]}
private Map<String, Person> getCoolestByPosition2(List<Employee> employees) {
// TODO
throw new UnsupportedOperationException();
return employees.stream()
.flatMap(this::toExclusivePersonPositionDuration)
.collect(
groupingBy(
PersonPositionDuration::getPosition,
collectingAndThen(maxBy(Comparator.comparing(PersonPositionDuration::getDuration)), p -> p.get().getPerson())
)
);
/*.collect(
toMap(
PersonPositionDuration::getPosition,
Function.identity(),
(p1, p2) -> p1.getDuration() > p2.getDuration() ? p1 : p2
)
).entrySet()
.stream()
.collect(
toMap(
Map.Entry::getKey,
e -> e.getValue().getPerson()
)
);*/
}

private Stream<? extends PersonPositionDuration> toExclusivePersonPositionDuration(Employee employee) {
return employee.getJobHistory()
.stream()
.collect(
toMap(JobHistoryEntry::getPosition,
JobHistoryEntry::getDuration,
(d1, d2) -> d1 + d2
)
)
.entrySet()
.stream()
.map(
entry -> new PersonPositionDuration(employee.getPerson(), entry.getKey(), entry.getValue())
);
}

private List<Employee> getEmployees() {
Expand Down
100 changes: 74 additions & 26 deletions src/test/java/part2/exercise/CollectorsExercise2.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package part2.exercise;

import data.Employee;
import data.JobHistoryEntry;
import data.Person;
import org.junit.Test;

import java.util.*;
Expand All @@ -16,7 +13,7 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.*;

public class CollectorsExercise2 {

Expand All @@ -31,20 +28,20 @@ private static String generateString() {
.collect(Collectors.joining());
}

private static String[] generateStringArray(int length) {
private static String[] generateStringArray(final int length) {
return Stream.generate(CollectorsExercise2::generateString)
.limit(length)
.toArray(String[]::new);
}

public static String pickString(String[] array) {
private static String pickString(final String[] array) {
return array[ThreadLocalRandom.current().nextInt(array.length)];
}

public static class Key {
private final String id;

public Key(String id) {
public Key(final String id) {
this.id = id;
}

Expand All @@ -53,14 +50,13 @@ public String getId() {
}

@Override
public boolean equals(Object o) {
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Key key = (Key) o;
final Key key = (Key) o;

return id.equals(key.id);

}

@Override
Expand All @@ -72,7 +68,7 @@ public int hashCode() {
public static class Value {
private final String keyId;

public Value(String keyId) {
public Value(final String keyId) {
this.keyId = keyId;
}

Expand All @@ -85,7 +81,7 @@ public static class Pair {
private final Key key;
private final Value value;

public Pair(Key key, Value value) {
public Pair(final Key key, final Value value) {
this.key = key;
this.value = value;
}
Expand All @@ -99,7 +95,7 @@ public Value getValue() {
}
}

public static List<Pair> generatePairs(int idCount, int length) {
public static List<Pair> generatePairs(final int idCount, final int length) {
final String[] ids = generateStringArray(idCount);

return Stream.generate(() -> new Pair(new Key(pickString(ids)), new Value(pickString(ids))))
Expand All @@ -112,7 +108,7 @@ private static class SubResult {
private final Map<String, List<Key>> knownKeys;
private final Map<String, List<Value>> valuesWithoutKeys;

public SubResult(Map<Key, List<Value>> subResult, Map<String, List<Key>> knownKeys, Map<String, List<Value>> valuesWithoutKeys) {
public SubResult(final Map<Key, List<Value>> subResult, final Map<String, List<Key>> knownKeys, final Map<String, List<Value>> valuesWithoutKeys) {
this.subResult = subResult;
this.knownKeys = knownKeys;
this.valuesWithoutKeys = valuesWithoutKeys;
Expand All @@ -139,7 +135,7 @@ public MapPair() {
this(new HashMap<>(), new HashMap<>());
}

public MapPair(Map<String, Key> keyById, Map<String, List<Value>> valueById) {
public MapPair(final Map<String, Key> keyById, final Map<String, List<Value>> valueById) {
this.keyById = keyById;
this.valueById = valueById;
}
Expand All @@ -154,9 +150,9 @@ public Map<String, List<Value>> getValueById() {
}

private static <K, V, M extends Map<K, V>>
BinaryOperator<M> mapMerger(BinaryOperator<V> mergeFunction) {
BinaryOperator<M> mapMerger(final BinaryOperator<V> mergeFunction) {
return (m1, m2) -> {
for (Map.Entry<K, V> e : m2.entrySet()) {
for (final Map.Entry<K, V> e : m2.entrySet()) {
m1.merge(e.getKey(), e.getValue(), mergeFunction);
}
return m1;
Expand All @@ -170,7 +166,32 @@ public void collectKeyValueMap() {
// В два прохода
// final Map<String, Key> keyMap1 = pairs.stream()...

final Map<String, Key> idToKey = pairs.stream()
.collect(
toMap(
pair -> pair.getKey().getId(),
Pair::getKey
)
);

// final Map<String, List<Value>> valuesMap1 = pairs.stream()...
final Map<Key, List<Value>> keyValuesMap1 = pairs.stream()
.collect(groupingBy(
pair -> pair.getValue().getKeyId(),
collectingAndThen(mapping(Pair::getValue, toList()), Function.identity())
))
.entrySet().stream()
.collect(
toMap(
pair -> idToKey.get(pair.getKey()),
Map.Entry::getValue,
(l1, l2) -> {
l1.addAll(l2);
return l1;
}
)
);


// В каждом Map.Entry id ключа должно совпадать с keyId для каждого значения в списке
// final Map<Key, List<Value>> keyValuesMap1 = valueMap1.entrySet().stream()...
Expand All @@ -180,20 +201,39 @@ public void collectKeyValueMap() {
.collect(new Collector<Pair, MapPair, MapPair>() {
@Override
public Supplier<MapPair> supplier() {
// TODO
throw new UnsupportedOperationException();
return MapPair::new;
}

@Override
public BiConsumer<MapPair, Pair> accumulator() {
// TODO add key and value to maps
throw new UnsupportedOperationException();
return (mapPair, pair) -> {
mapPair.getKeyById().put(pair.getKey().getId(), pair.getKey());
mapPair.getValueById().merge(
pair.getValue().getKeyId(),
Collections.singletonList(pair.getValue()),
this::listMerger
);
};
}

private List<Value> listMerger(List<Value> values, List<Value> values1) {
values.addAll(values1);
return values;
}

@Override
public BinaryOperator<MapPair> combiner() {
// TODO use mapMerger
throw new UnsupportedOperationException();
return (p1, p2) -> {
BinaryOperator<Map<String, Key>> toKey = mapMerger((k1, k2) -> k1);
BinaryOperator<Map<String, List<Value>>> toValues = mapMerger((v1, v2) -> {
v1.addAll(v2);
return v1;
});

toKey.apply(p1.getKeyById(),p2.getKeyById());
toValues.apply(p1.getValueById(),p2.getValueById());
return new MapPair(p1.getKeyById(),p2.getValueById());
};
}

@Override
Expand All @@ -212,15 +252,23 @@ public Set<Characteristics> characteristics() {
final Map<String, Key> keyMap2 = res2.getKeyById();
final Map<String, List<Value>> valuesMap2 = res2.getValueById();

// final Map<Key, List<Value>> keyValuesMap2 = valueMap2.entrySet().stream()...

final Map<Key, List<Value>> keyValuesMap2 = valuesMap2.entrySet().stream()
.collect(
toMap(
pair -> idToKey.get(pair.getKey()),
Map.Entry::getValue,
(l1, l2) -> {
l1.addAll(l2);
return l1;
}
)
);
// Получение результата сразу:

final SubResult res3 = pairs.stream()
.collect(new Collector<Pair, SubResult, SubResult>() {
@Override
public Supplier<SubResult> supplier() {
// TODO
throw new UnsupportedOperationException();
}

Expand Down