스트림에서 Collections.toMap()을 사용할 때 목록의 반복 순서를 유지하려면 어떻게 해야 합니까?
작성 중입니다.Map
에서List
다음과 같습니다.
List<String> strings = Arrays.asList("a", "bb", "ccc");
Map<String, Integer> map = strings.stream()
.collect(Collectors.toMap(Function.identity(), String::length));
이전과 같은 반복 순서를 유지하고 싶다.List
를 작성하려면 어떻게 해야 하나요?LinkedHashMap
사용방법Collectors.toMap()
방법?
의 2-파라미터 버전에서는HashMap
:
public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper)
{
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
4-파라미터 버전을 사용하려면 다음을 대체할 수 있습니다.
Collectors.toMap(Function.identity(), String::length)
포함:
Collectors.toMap(
Function.identity(),
String::length,
(u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
},
LinkedHashMap::new
)
아니면 좀 더 깔끔하게 하기 위해서 새로 쓰세요.toLinkedMap()
방법 및 사용방법:
public class MoreCollectors
{
public static <T, K, U> Collector<T, ?, Map<K,U>> toLinkedMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper)
{
return Collectors.toMap(
keyMapper,
valueMapper,
(u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
},
LinkedHashMap::new
);
}
}
나만의 것을 만들어라Supplier
,Accumulator
그리고.Combiner
:
List<String> myList = Arrays.asList("a", "bb", "ccc");
// or since java 9 List.of("a", "bb", "ccc");
LinkedHashMap<String, Integer> mapInOrder = myList
.stream()
.collect(
LinkedHashMap::new, // Supplier LinkedHashMap to keep the order
(map, item) -> map.put(item, item.length()), // Accumulator
Map::putAll); // Combiner
System.out.println(mapInOrder); // prints {a=1, bb=2, ccc=3}
이 문제에 대한 적절한 해결책은
현재 ----> 2 파라미터 버전
Map<Integer, String> mapping = list.stream().collect(Collectors.toMap(Entity::getId, Entity::getName));
오른쪽 ----> Collectors.toMap의 4 파라미터 버전을 사용하여 공급업체에 새 Linked HashMap을 제공하도록 지시합니다.
Map<Integer, String> mapping = list.stream().collect(Collectors.toMap(Entity::getId, Entity::getName, (u, v) -> u, LinkedHashMap::new));
이게 도움이 될 거야.
코틀린에서는 질서를 유지하고 있습니다.
fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V>
지정된 쌍의 컬렉션에서 모든 키와 값의 쌍을 포함하는 새 맵을 반환합니다.
반환된 맵은 원래 컬렉션의 엔트리 반복 순서를 유지합니다.두 쌍의 키 중 하나가 동일한 키를 가질 경우 마지막 쌍이 맵에 추가됩니다.
실장은 다음과 같습니다.
public fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V> {
if (this is Collection) {
return when (size) {
0 -> emptyMap()
1 -> mapOf(if (this is List) this[0] else iterator().next())
else -> toMap(LinkedHashMap<K, V>(mapCapacity(size)))
}
}
return toMap(LinkedHashMap<K, V>()).optimizeReadOnlyMap()
}
용도는 다음과 같습니다.
val strings = listOf("a", "bb", "ccc")
val map = strings.map { it to it.length }.toMap()
의 기본 컬렉션map
는 입니다.LinkedHashMap
(삽입 순서입니다).
일부 필드별로 객체 배열을 매핑하는 간단한 기능:
public static <T, E> Map<E, T> toLinkedHashMap(List<T> list, Function<T, E> someFunction) {
return list.stream()
.collect(Collectors.toMap(
someFunction,
myObject -> myObject,
(key1, key2) -> key1,
LinkedHashMap::new)
);
}
Map<String, MyObject> myObjectsByIdMap1 = toLinkedHashMap(
listOfMyObjects,
MyObject::getSomeStringField()
);
Map<Integer, MyObject> myObjectsByIdMap2 = toLinkedHashMap(
listOfMyObjects,
MyObject::getSomeIntegerField()
);
Java 9에서는 원래 목록과 같은 순서로 맵엔트리 목록을 수집할 수 있습니다.
List<String> strings = Arrays.asList("a", "bb", "ccc");
List<Map.Entry<String, Integer>> entries = strings.stream()
.map(e -> Map.entry(e, e.length()))
.collect(Collectors.toList());
System.out.println(entries); // [a=1, bb=2, ccc=3]
또는 동일한 방법으로 단일 엔트리를 사용하여 맵 목록을 수집할 수 있습니다.
List<String> strings = Arrays.asList("a", "bb", "ccc");
List<Map<String, Integer>> maps = strings.stream()
.map(e -> Map.of(e, e.length()))
.collect(Collectors.toList());
System.out.println(maps); // [{a=1}, {bb=2}, {ccc=3}]
언급URL : https://stackoverflow.com/questions/29090277/how-do-i-keep-the-iteration-order-of-a-list-when-using-collections-tomap-on-a
'programing' 카테고리의 다른 글
Self-JOIN SQL 쿼리 성능 향상 (0) | 2022.11.01 |
---|---|
롬복의 슈퍼 컨스트럭터에 전화하는 방법 (0) | 2022.11.01 |
PHP에서 ++$i와 $i++의 차이점은 무엇입니까? (0) | 2022.11.01 |
war/WEB-INF 폴더의 리소스에 대한 파일 경로 (0) | 2022.11.01 |
세트를 어레이로 변환하는 방법 (0) | 2022.11.01 |