“This is the second day of my participation in the November Gwen Challenge. See details of the event: The last Gwen Challenge 2021”.
In daily development, converting from one Map to another is a basic operation, so how do we implement this scenario? Is there a simpler way to do this?
Example scenario
Now let’s give a simple example
We want to convert a Map
to Map
Start by providing a public method to create a Map
private static <T> Map<String, T> newMap(String key, T val, Object... kv) {
Map<String, T> ans = new HashMap<>(8);
ans.put(key, val);
for (int i = 0, size = kv.length; i < size; i += 2) {
ans.put(String.valueOf(kv[i]), (T) kv[i + 1]);
}
return ans;
}
Copy the code
Method 1: Basic for loop conversion
This is the easiest way to think of and implement it, and it’s just a for loop
@Test
public void forEachParse(a) {
Map<String, Integer> map = newMap("k".1."a".2."b".3);
Map<String, String> ans = new HashMap<>(map.size());
for (Map.Entry<String, Integer> entry: map.entrySet()) {
ans.put(entry.getKey(), String.valueOf(entry.getValue()));
}
System.out.println(ans);
}
Copy the code
The advantages of this approach are obvious, easy to implement, intuitive business;
Disadvantages are poor reusability and large amount of code (compared to the following case)
Mode 2: streaming use of containers
Streaming operations are provided in jdk1.8, and transformations can be implemented in this way as well
@Test
public void stream(a) {
Map<String, Integer> map = newMap("k".1."a".2."b".3);
Map<String, String> ans = map.entrySet().stream().collect(
Collectors.toMap(Map.Entry::getKey, s -> String.valueOf(s.getValue()), (a, b) -> a));
System.out.println(ans);
}
Copy the code
The advantage of using stream is that it is chained and has less code. The disadvantage is that the reading experience will be worse than the above (of course, this depends on the individual, some friends are more used to reading this kind of chained code).
Method 3: Guava’s Trasform method
At the code level, the above two are not intuitive, but those of you familiar with Guava will probably be familiar with the following code
@Test
public void transfer(a) {
Map<String, Integer> map = newMap("k".1."a".2."b".3);
Map<String, String> ans = Maps.transformValues(map, String::valueOf);
System.out.println(ans);
}
Copy the code
The core logic is a single line maps.transformvalues (map, String::valueOf), which implements our map transformation requirements
The obvious advantage of this approach is that it is indirect and intuitive; Of course, the disadvantage is that you need to introduce guava and become familiar with guava
Finally, what is the purpose of this article?
We can use Guava’s maps.transformValues to implement map transformations, but what if we were to implement a utility class to support this scenario?
Just provide a conversion method?
Step 1: A generic transformation interface
public <K, T, V> Map<K, V> transform(Map<K, T> map) {}Copy the code
After defining the interface above, the natural drawback is the lack of a value conversion implementation
Step 2: Define the value conversion
The idea of the Function interface is used to define the transformation class
public <K, T, V> Map<K, V> transform(Map<K, T> map, Function<T, V> func) {}Copy the code
Jdk1.8 does not support functional programming, so how can we implement it?
At this time, compare the implementation of Guava, and then masturbate a knowledge point in hand
A gray contact information
All letter is better than no book, the above content, purely one’s words, due to the limited personal ability, it is hard to avoid omissions and mistakes, such as finding bugs or better suggestions, welcome criticism and correction, not grudging gratitude
- Personal site: blog.hhui.top
- Micro Blog address: Small Gray Blog
- QQ: a gray /3302797840
- Wechat official account: One Grey Blog