Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit03c2949

Browse files
committed
adding MapLens#mappingValues, a lens over a map with mapped values
1 parent538b645 commit03c2949

File tree

2 files changed

+63
-11
lines changed

2 files changed

+63
-11
lines changed

‎src/main/java/com/jnape/palatable/lambda/lens/lenses/MapLens.java

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
packagecom.jnape.palatable.lambda.lens.lenses;
22

3+
importcom.jnape.palatable.lambda.functions.builtin.fn2.Filter;
34
importcom.jnape.palatable.lambda.lens.Lens;
45

56
importjava.util.Collection;
@@ -8,11 +9,16 @@
89
importjava.util.Map;
910
importjava.util.Optional;
1011
importjava.util.Set;
12+
importjava.util.function.Function;
1113

14+
importstaticcom.jnape.palatable.lambda.functions.builtin.fn2.Eq.eq;
15+
importstaticcom.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
16+
importstaticcom.jnape.palatable.lambda.functions.builtin.fn2.ToCollection.toCollection;
1217
importstaticcom.jnape.palatable.lambda.lens.Lens.lens;
1318
importstaticcom.jnape.palatable.lambda.lens.Lens.simpleLens;
1419
importstaticcom.jnape.palatable.lambda.lens.functions.View.view;
1520
importstaticcom.jnape.palatable.lambda.lens.lenses.OptionalLens.unLiftA;
21+
importstaticjava.util.stream.Collectors.toMap;
1622
importstaticjava.util.stream.Collectors.toSet;
1723

1824
/**
@@ -24,8 +30,7 @@ private MapLens() {
2430
}
2531

2632
/**
27-
* Convenience static factory method for creating a lens that focuses on a copy of a Map. Useful for composition to
28-
* avoid mutating a map reference.
33+
* A lens that focuses on a copy of a Map. Useful for composition to avoid mutating a map reference.
2934
*
3035
* @param <K> the key type
3136
* @param <V> the value type
@@ -36,8 +41,7 @@ public static <K, V> Lens.Simple<Map<K, V>, Map<K, V>> asCopy() {
3641
}
3742

3843
/**
39-
* Convenience static factory method for creating a lens that focuses on a value at a key in a map, as an {@link
40-
* Optional}.
44+
* A lens that focuses on a value at a key in a map, as an {@link Optional}.
4145
*
4246
* @param k the key to focus on
4347
* @param <K> the key type
@@ -52,8 +56,7 @@ public static <K, V> Lens<Map<K, V>, Map<K, V>, Optional<V>, V> valueAt(K k) {
5256
}
5357

5458
/**
55-
* Convenience static factory method for creating a lens that focuses on a value at a key in a map, falling back to
56-
* <code>defaultV</code> if the value is missing.
59+
* A lens that focuses on a value at a key in a map, falling back to <code>defaultV</code> if the value is missing.
5760
*
5861
* @param k the key to focus on
5962
* @param defaultValue the default value to use in case of a missing value at key
@@ -67,7 +70,7 @@ public static <K, V> Lens.Simple<Map<K, V>, V> valueAt(K k, V defaultValue) {
6770
}
6871

6972
/**
70-
*Convenience static factory method for creating a lens that focuses on the keys of a map.
73+
*A lens that focuses on the keys of a map.
7174
*
7275
* @param <K> the key type
7376
* @param <V> the value type
@@ -84,8 +87,8 @@ public static <K, V> Lens.Simple<Map<K, V>, Set<K>> keys() {
8487
}
8588

8689
/**
87-
*Convenience static factory method for creating alens that focuses on the values of a map. In the case of
88-
*updating the map, only the entries with a value listedin the update collection of values are kept.
90+
*Alens that focuses on the values of a map. In the case of updating the map, only the entries with a value listed
91+
* in the update collection of values are kept.
8992
*
9093
* @param <K> the key type
9194
* @param <V> the value type
@@ -104,8 +107,8 @@ public static <K, V> Lens.Simple<Map<K, V>, Collection<V>> values() {
104107
}
105108

106109
/**
107-
*Convenience static factory method for creating alens that focuses on the inverse of a map (keys and values
108-
*swapped). In the case of multiple equal valuesbecoming keys, the last one wins.
110+
*Alens that focuses on the inverse of a map (keys and values swapped). In the case of multiple equal values
111+
* becoming keys, the last one wins.
109112
*
110113
* @param <K> the key type
111114
* @param <V> the value type
@@ -122,4 +125,27 @@ public static <K, V> Lens.Simple<Map<K, V>, Map<V, K>> inverted() {
122125
returnm;
123126
});
124127
}
128+
129+
/**
130+
* A lens that focuses on a map while mapping its values with the mapping function.
131+
*
132+
* @param fn the mapping function
133+
* @param <K> the key type
134+
* @param <V> the unfocused map value type
135+
* @param <V2> the focused map value type
136+
* @return a lens that focuses on a map while mapping its values
137+
*/
138+
publicstatic <K,V,V2>Lens.Simple<Map<K,V>,Map<K,V2>>mappingValues(Function<?superV, ?extendsV2>fn) {
139+
returnLens.simpleLens(m ->m.entrySet().stream().collect(toMap(Map.Entry::getKey,kv ->fn.apply(kv.getValue()))),
140+
(s,b) -> {
141+
//todo: remove this madness upon arrival of either invertible functions or Iso<V,V2>
142+
Set<K>retainKeys =Filter.<Map.Entry<K,V>>filter(kv ->eq(fn.apply(kv.getValue()),b.get(kv.getKey())))
143+
.andThen(map(Map.Entry::getKey))
144+
.andThen(toCollection(HashSet::new))
145+
.apply(s.entrySet());
146+
Map<K,V>copy =newHashMap<>(s);
147+
copy.keySet().retainAll(retainKeys);
148+
returncopy;
149+
});
150+
}
125151
}

‎src/test/java/com/jnape/palatable/lambda/lens/lenses/MapLensTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
importstaticcom.jnape.palatable.lambda.lens.functions.Set.set;
1515
importstaticcom.jnape.palatable.lambda.lens.functions.View.view;
1616
importstaticcom.jnape.palatable.lambda.lens.lenses.MapLens.keys;
17+
importstaticcom.jnape.palatable.lambda.lens.lenses.MapLens.mappingValues;
1718
importstaticjava.util.Arrays.asList;
1819
importstaticjava.util.Collections.emptyMap;
20+
importstaticjava.util.Collections.singletonMap;
21+
importstaticjava.util.Collections.unmodifiableMap;
1922
importstaticorg.junit.Assert.assertEquals;
2023
importstaticorg.junit.Assert.assertNotSame;
2124
importstaticorg.junit.Assert.assertSame;
@@ -134,4 +137,27 @@ public void invertedFocusesOnMapWithKeysAndValuesSwitched() {
134137
put(1,"foo");
135138
}},view(inverted,withDuplicateValues));
136139
}
140+
141+
@Test
142+
publicvoidmappingValuesRetainsMapStructureWithMappedValues() {
143+
Map<String,String>m =unmodifiableMap(newHashMap<String,String>() {{
144+
put("foo","1");
145+
put("bar","2");
146+
put("baz","3");
147+
}});
148+
Lens.Simple<Map<String,String>,Map<String,Integer>>mappingValues =mappingValues(Integer::parseInt);
149+
150+
assertEquals(newHashMap<String,Integer>() {{
151+
put("foo",1);
152+
put("bar",2);
153+
put("baz",3);
154+
}},view(mappingValues,m));
155+
156+
Map<String,String>updated =set(mappingValues,unmodifiableMap(newHashMap<String,Integer>() {{
157+
put("foo",2);
158+
put("bar",1);
159+
put("baz",3);
160+
}}),m);
161+
assertEquals(singletonMap("baz","3"),updated);
162+
}
137163
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp