Skip to content

Part 3 is done #87

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 1 commit 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
216 changes: 115 additions & 101 deletions src/test/java/part2/exercise/CollectorsExercise2.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public Map<String, List<Key>> getKnownKeys() {
}
}

private static class MapPair {
public static class MapPair {
private final Map<String, Key> keyById;
private final Map<String, List<Value>> valueById;

Expand All @@ -151,107 +151,121 @@ public Map<String, Key> getKeyById() {
public Map<String, List<Value>> getValueById() {
return valueById;
}
}

private static <K, V, M extends Map<K, V>>
BinaryOperator<M> mapMerger(BinaryOperator<V> mergeFunction) {
return (m1, m2) -> {
for (Map.Entry<K, V> e : m2.entrySet()) {
m1.merge(e.getKey(), e.getValue(), mergeFunction);
}
return m1;
};
}
public void put(Pair p) {
keyById.put(p.getKey().getId(), p.getKey());
final ArrayList<Value> value = new ArrayList<>();
value.add(p.getValue());
valueById.merge(p.getValue().getKeyId(),
value,
(l1, l2) -> {
l1.addAll(l2);
return l1;
});


@Test
public void collectKeyValueMap() {
final List<Pair> pairs = generatePairs(10, 100);

// В два прохода
// final Map<String, Key> keyMap1 = pairs.stream()...

// final Map<String, List<Value>> valuesMap1 = pairs.stream()...

// В каждом Map.Entry id ключа должно совпадать с keyId для каждого значения в списке
// final Map<Key, List<Value>> keyValuesMap1 = valueMap1.entrySet().stream()...

// В 1 проход в 2 Map с использованием MapPair и mapMerger
final MapPair res2 = pairs.stream()
.collect(new Collector<Pair, MapPair, MapPair>() {
@Override
public Supplier<MapPair> supplier() {
// TODO
throw new UnsupportedOperationException();
}

@Override
public BiConsumer<MapPair, Pair> accumulator() {
// TODO add key and value to maps
throw new UnsupportedOperationException();
}

@Override
public BinaryOperator<MapPair> combiner() {
// TODO use mapMerger
throw new UnsupportedOperationException();
}

@Override
public Function<MapPair, MapPair> finisher() {
return Function.identity();
}

@Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(
Characteristics.UNORDERED,
Characteristics.IDENTITY_FINISH));
}
});

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 SubResult res3 = pairs.stream()
.collect(new Collector<Pair, SubResult, SubResult>() {
@Override
public Supplier<SubResult> supplier() {
// TODO
throw new UnsupportedOperationException();
}

@Override
public BiConsumer<SubResult, Pair> accumulator() {
// TODO add key to map, then check value.keyId and add it to one of maps
throw new UnsupportedOperationException();
}

@Override
public BinaryOperator<SubResult> combiner() {
// TODO use mapMerger, then check all valuesWithoutKeys
throw new UnsupportedOperationException();
}

@Override
public Function<SubResult, SubResult> finisher() {
// TODO use mapMerger, then check all valuesWithoutKeys
throw new UnsupportedOperationException();
}

@Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(
Characteristics.UNORDERED));
}
});

final Map<Key, List<Value>> keyValuesMap3 = res3.getSubResult();

// compare results
}
}

}
public static <K, V, M extends Map<K, V>>
BinaryOperator<M> mapMerger(BinaryOperator<V> mergeFunction) {
return (m1, m2) -> {
for (Map.Entry<K, V> e : m2.entrySet()) {
m1.merge(e.getKey(), e.getValue(), mergeFunction);
}
return m1;
};
}

@Test
public void collectKeyValueMap() {
final List<Pair> pairs = generatePairs(10, 100);

// В два прохода
// final Map<String, Key> keyMap1 = pairs.stream()...

// final Map<String, List<Value>> valuesMap1 = pairs.stream()...

// В каждом Map.Entry id ключа должно совпадать с keyId для каждого значения в списке
// final Map<Key, List<Value>> keyValuesMap1 = valueMap1.entrySet().stream()...

// В 1 проход в 2 Map с использованием MapPair и mapMerger
final MapPair res2 = pairs.stream()
.collect(new Collector<Pair, MapPair, MapPair>() {
@Override
public Supplier<MapPair> supplier() {
// TODO
throw new UnsupportedOperationException();
}

@Override
public BiConsumer<MapPair, Pair> accumulator() {
// TODO add key and value to maps
throw new UnsupportedOperationException();
}

@Override
public BinaryOperator<MapPair> combiner() {
// TODO use mapMerger
throw new UnsupportedOperationException();
}

@Override
public Function<MapPair, MapPair> finisher() {
return Function.identity();
}

@Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(
Characteristics.UNORDERED,
Characteristics.IDENTITY_FINISH));
}
});

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 SubResult res3 = pairs.stream()
.collect(new Collector<Pair, SubResult, SubResult>() {
@Override
public Supplier<SubResult> supplier() {
// TODO
throw new UnsupportedOperationException();
}

@Override
public BiConsumer<SubResult, Pair> accumulator() {
// TODO add key to map, then check value.keyId and add it to one of maps
throw new UnsupportedOperationException();
}

@Override
public BinaryOperator<SubResult> combiner() {
// TODO use mapMerger, then check all valuesWithoutKeys
throw new UnsupportedOperationException();
}

@Override
public Function<SubResult, SubResult> finisher() {
// TODO use mapMerger, then check all valuesWithoutKeys
throw new UnsupportedOperationException();
}

@Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(
Characteristics.UNORDERED));
}
});

final Map<Key, List<Value>> keyValuesMap3 = res3.getSubResult();

// compare results
}

}
120 changes: 108 additions & 12 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 @@ -34,31 +37,124 @@ 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();
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<>(
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 p -> new Pair<>(
c1.finisher().apply(p.getA()),
c2.finisher().apply(p.getB()));
}

@Override
public Set<Characteristics> characteristics() {
Set<Characteristics> set = new HashSet<>();
set.addAll(c1.characteristics());
set.addAll(c2.characteristics());
return set;
}
};
}

@Test
public void collectKeyValueMap() {
// TODO see CollectorsExercise1::collectKeyValueMap
// В 1 проход в 2 Map с использованием MapPair и mapMerger
// final MapPair res2 = pairs.stream()
// .collect(new Collector<Pair, MapPair, MapPair>() {

// Перепишите решение в слещующем виде:
final List<CollectorsExercise2.Pair> pairs = CollectorsExercise2.generatePairs(10, 100);

final Pair<Map<String, Key>, Map<String, List<Value>>> res2 = pairs.stream()
final Map<Key, List<Value>> res1 = pairs.stream()
.collect(collectingAndThen(
new Collector<CollectorsExercise2.Pair, CollectorsExercise2.MapPair, CollectorsExercise2.MapPair>() {
@Override
public Supplier<CollectorsExercise2.MapPair> supplier() {

return CollectorsExercise2.MapPair::new;
}

public BiConsumer<CollectorsExercise2.MapPair, CollectorsExercise2.Pair> accumulator() {

return CollectorsExercise2.MapPair::put;
}

@Override
public BinaryOperator<CollectorsExercise2.MapPair> combiner() {

return (mapPair, mapPair2) -> {
BinaryOperator<Map<String, Key>> keyMerger = CollectorsExercise2.mapMerger((v1, v2) -> v1);
keyMerger.apply(mapPair.getKeyById(), mapPair2.getKeyById());
BinaryOperator<Map<String, List<Value>>> valueMerger =
CollectorsExercise2.mapMerger((v1, v2) -> {
v1.addAll(v2);
return v1;
});
valueMerger.apply(mapPair.getValueById(), mapPair2.getValueById());
return mapPair;
};
}

@Override
public Function<CollectorsExercise2.MapPair, CollectorsExercise2.MapPair> finisher() {
return Function.identity();
}

@Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(
Characteristics.UNORDERED,
Characteristics.IDENTITY_FINISH));
}
},
(CollectorsExercise2.MapPair mmp) -> mmp.getKeyById().entrySet().stream()
.map(kp -> new AbstractMap.SimpleEntry<>(kp.getValue(), mmp.getValueById().get(kp.getKey())))
.collect(toMap(
Map.Entry::getKey,
Map.Entry::getValue
))
)
);


final Map<Key, List<Value>> res2 = pairs.stream()
.collect(
paired(
mapping(CollectorsExercise2.Pair::getKey, toMap(Key::getId, Function.identity(), (x, y) -> x)),
mapping(CollectorsExercise2.Pair::getValue, groupingBy(Value::getKeyId))
collectingAndThen(
paired(
mapping(CollectorsExercise2.Pair::getKey,
toMap(Key::getId, Function.identity(), (x, y) -> x)),
mapping(CollectorsExercise2.Pair::getValue,
groupingBy(Value::getKeyId))
),
mmp -> mmp.getA().entrySet().stream()
.map(kp -> new AbstractMap.SimpleEntry<>(kp.getValue(), mmp.getB().get(kp.getKey())))
.collect(toMap(
Map.Entry::getKey,
Map.Entry::getValue
))
)
);


// TODO tests
throw new UnsupportedOperationException();
assertEquals(res1, res2);
}

}
Loading