방금 Java 8을 살펴보기 시작했고 람다를 시험해보기 위해 최근에 작성한 아주 간단한 것을 다시 작성하려고 생각했습니다. 새 맵의 열이 첫 번째 맵의 열에 대한 방어 적 사본 인 문자열에서 열로의 맵을 다른 문자열에서 열로의 맵으로 바꿔야합니다. 열에 복사 생성자가 있습니다. 내가 지금까지 가장 가까운 것은 다음과 같습니다.
Map<String, Column> newColumnMap= new HashMap<>();
originalColumnMap.entrySet().stream().forEach(x -> newColumnMap.put(x.getKey(), new Column(x.getValue())));
그러나 더 좋은 방법이 있어야한다고 확신하며 조언을 해 주셔서 감사합니다.
답변
수집기를 사용할 수 있습니다 .
import java.util.*;
import java.util.stream.Collectors;
public class Defensive {
public static void main(String[] args) {
Map<String, Column> original = new HashMap<>();
original.put("foo", new Column());
original.put("bar", new Column());
Map<String, Column> copy = original.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> new Column(e.getValue())));
System.out.println(original);
System.out.println(copy);
}
static class Column {
public Column() {}
public Column(Column c) {}
}
}
답변
Map<String, Integer> map = new HashMap<>();
map.put("test1", 1);
map.put("test2", 2);
Map<String, Integer> map2 = new HashMap<>();
map.forEach(map2::put);
System.out.println("map: " + map);
System.out.println("map2: " + map2);
// Output:
// map: {test2=2, test1=1}
// map2: {test2=2, test1=1}
이 forEach
방법을 사용하여 원하는 것을 수행 할 수 있습니다.
당신이하고있는 일은 :
map.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer integer) {
map2.put(s, integer);
}
});
우리는 람다로 단순화 할 수 있습니다 :
map.forEach((s, integer) -> map2.put(s, integer));
그리고 우리는 단지 기존 메소드를 호출하기 때문에 메소드 reference를 사용할 수 있습니다 .
map.forEach(map2::put);
답변
HashMap.clone
내부적으로 리해시를 수행 하기 때문에 모든 항목을 새 맵에 다시 삽입하지 않는 방법이 가장 빠릅니다 .
Map<String, Column> newColumnMap = originalColumnMap.clone();
newColumnMap.replaceAll((s, c) -> new Column(c));
답변
간단하게 유지하고 Java 8 :-를 사용하십시오.
Map<String, AccountGroupMappingModel> mapAccountGroup=CustomerDAO.getAccountGroupMapping();
Map<String, AccountGroupMappingModel> mapH2ToBydAccountGroups =
mapAccountGroup.entrySet().stream()
.collect(Collectors.toMap(e->e.getValue().getH2AccountGroup(),
e ->e.getValue())
);
답변
프로젝트에서 Guava (v11 최소)를 사용하는 경우 Maps :: transformValues를 사용할 수 있습니다 .
Map<String, Column> newColumnMap = Maps.transformValues(
originalColumnMap,
Column::new // equivalent to: x -> new Column(x)
)
참고 :이 맵의 값은 느리게 평가됩니다. 변환 비용이 비싸면 Guava 문서에서 제안한 것과 같이 결과를 새 맵에 복사 할 수 있습니다.
To avoid lazy evaluation when the returned map doesn't need to be a view, copy the returned map into a new map of your choosing.
답변
다음은 일종의 변환을 수행해야하는 경우 키와 값에 동시에 액세스 할 수있는 또 다른 방법입니다.
Map<String, Integer> pointsByName = new HashMap<>();
Map<String, Integer> maxPointsByName = new HashMap<>();
Map<String, Double> gradesByName = pointsByName.entrySet().stream()
.map(entry -> new AbstractMap.SimpleImmutableEntry<>(
entry.getKey(), ((double) entry.getValue() /
maxPointsByName.get(entry.getKey())) * 100d))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
답변
타사 라이브러리를 사용하는 것이 마음에 들지 않으면 cyclops-react lib에 Map을 포함한 모든 JDK Collection 유형에 대한 확장이 있습니다 . map 또는 bimap 메소드를 직접 사용하여 맵을 변환 할 수 있습니다. MapX는 기존 Map으로 구성 할 수 있습니다.
MapX<String, Column> y = MapX.fromMap(orgColumnMap)
.map(c->new Column(c.getValue());
키를 변경하려면 다음을 쓸 수 있습니다
MapX<String, Column> y = MapX.fromMap(orgColumnMap)
.bimap(this::newKey,c->new Column(c.getValue());
bimap을 사용하여 키와 값을 동시에 변환 할 수 있습니다.
MapX가 Map을 확장함에 따라 생성 된 맵을 다음과 같이 정의 할 수도 있습니다.
Map<String, Column> y
