감소 : Elegantly create map with object fields as key/value from object stream in Java 8합니다. 요약 목표는 연령과 키를 가진지도를 얻는 것이었고 사람의 취미는 Set
입니다.자바 8 stream.collect (... groupingBy (... 매핑 (... 감소))) 내가 <code>groupingBy</code>, <code>mapping</code> 다음과 같은 질문에 <code>reducing</code> 사용하여 솔루션을 놀았 BinaryOperator-사용
내가 생각해 낸 해결책 중 하나 (이상한 것은 아니지만 그게 중요한 것이 아닙니다)에는 이상한 행동이있었습니다. 입력으로 다음 목록으로
:
List<Person> personList = Arrays.asList(
new Person(/* name */ "A", /* age */ 23, /* hobbies */ asList("a")),
new Person("BC", 24, asList("b", "c")),
new Person("D", 23, asList("d")),
new Person("E", 23, asList("e"))
);
하고 다음 솔루션 :
Collector<List<String>, ?, Set<String>> listToSetReducer = Collectors.reducing(new HashSet<>(), HashSet::new, (strings, strings2) -> {
strings.addAll(strings2);
return strings;
});
Map<Integer, Set<String>> map = personList.stream()
.collect(Collectors.groupingBy(o -> o.age,
Collectors.mapping(o -> o.hobbies, listToSetReducer)));
System.out.println("map = " + map);
내가 가진 :
map = {23=[a, b, c, d, e], 24=[a, b, c, d, e]}
분명 내가 기대했다되지 것을. 난 그냥 내가 예상 결과를 얻을
(strings2, strings)
에 (환원 컬렉터의) 바이너리 연산자의
(strings, strings2)
의 순서를 교체 할 경우 지금
map = {23=[a, d, e], 24=[b, c]}
: 차라리이 예상. 그래서 나는 무엇을 여기에서 놓쳤 느냐? reducing
- 콜렉터를 잘못 해석 했습니까? 또는 어떤 문서를 그리워 했는가? 내 사용법이 예상대로 작동하지 않는다는 것을 분명하게 알 수 있습니까?
자바 버전은 1.8.0_121입니다.
재미있는 .. 심지어 Collectors''에서 flatMapping''찾기 (또는'hobbies.stream를 (적용하기) '과 함께 작동하도록) 시도 처음에는 . 좋은 소식입니다. 오 이런, 나는 결합자를 오퍼레이터와 섞었다. 따라서 매개 변수를 전환하면 올바른 결과가 도출되는 것은 우연한 일입니다. 귀하의 설명에 감사드립니다! – Roland
예, 순차적 인 컨텍스트에서 감소 함수는 항상 'f (이전, 다음)'로 평가됩니다. 반면 '이전'은 첫 번째 평가의 ID 값이고 이후 평가의 이전 결과입니다. 그러므로 (a, b) -> a는 항등 값으로 끝나고, (a, b) -> b는 매퍼 함수에 의해 생성 된 신선한 값을 사용하게됩니다. 그러나 병렬 평가에서 두 인수는 이전 부분 평가의 결과 일 수 있으며 부분 결과가 비어있을 수 있으므로 두 인수 중 하나가 신원 값이 될 수 있으므로 두 번째 인수를 사용하는 것이 신뢰할 수있는 수정이 아닙니다. – Holger