[Java] Map # merge is hard to understand.

While now

Even though Java 9 was released the other day, I dared to start studying Java 8 at this time. The lap delay is also good, but the new features of Java 8 are still too nice and impressed. You can find a number of easy-to-understand articles about the new features of Java 8 by google, so I will leave the whole explanation to them, but here I did not understand & there is no article that explains in too much detail Map # merge Make a note of the movement of.

Map#merge

The process of "overwrite the value with" CCC "if the key" key1 "exists in the map, and add the value" BBB "as a new key if it does not exist" is performed in Java 7 and Java 8. Let's compare how to write.

Up to Java7 ("key1"Exists)


Map<String, String> map = new HashMap<String, String>();
map.put("key1", "AAA");

System.out.println(map);

if (map.containsKey("key1")) {
	map.put("key1", "CCC");
} else {
	map.put("key1", "BBB");
}

System.out.println(map);

Execution result


{key1=AAA}
{key1=CCC}

Up to Java7 ("key1"Does not exist)


Map<String, String> map = new HashMap<String, String>();

System.out.println(map);

if (map.containsKey("key1")) {
	map.put("key1", "CCC");
} else {
	map.put("key1", "BBB");
}

System.out.println(map);

Execution result


{}
{key1=BBB}

If you try using Map # merge added in Java 8, it will be as follows. If the key ("key1") specified in the first argument does not exist in Map, the value of the second argument ("BBB") is put in that key ("key1"), and if the key exists, the third argument The remapping function of is executed.

Java8("key1"Exists)


Map<String, String> map = new HashMap<String, String>();
map.put("key1", "AAA");

System.out.println(map);

map.merge("key1", "BBB", 
	(v1, v2) -> {
		return "CCC";
	});

System.out.println(map);

Execution result


{key1=AAA}
{key1=CCC}

Java8("key1"Does not exist)


Map<String, String> map = new HashMap<String, String>();

System.out.println(map);

map.merge("key1", "BBB", 
	(v1, v2) -> {
		return "CCC";
	});

System.out.println(map);

Execution result


{}
{key1=BBB}

What are the two arguments?

I was wondering what are the two arguments passed to the remapping function that is called when the key exists in the Map? about it. The v1 and v2 in the above example are not used at all.

So for the time being, let's output what is being passed.

Java8("key1"Exists)


Map<String, String> map = new HashMap<String, String>();
map.put("key1", "AAA");

System.out.println(map);

map.merge("key1", "BBB", 
	(v1, v2) -> {
		Sytem.out.printf("v1:%s, v2:%s\n", v1, v2);
		return "CCC";
	});

System.out.println(map);

Execution result


{key1=AAA}
v1:AAA, v2:BBB
{key1=CCC}

have become. That is, when the key "key1" exists, the value that already exists ("AAA" in the example) and the value to be set if it does not exist ("BBB" in the example) are passed to this function. However, even if the "value to be set when the key does not exist" is passed as an argument, I think that it is rarely used when the key exists. Passing this value may be useful for limited purposes, such as when concatenating this value to an existing value (string). In the case of a simple replacement like this one, writing up to Java 7 is rather easier to understand.

By the way, simple concatenation can be realized by specifying String :: concat in the remapping function as shown below.

Simple connection is OK with this!


Map<String, String> map = new HashMap<String, String>();

map.put("key1", "AAA");

System.out.println(map);

map.merge("key1", "BBB", String::concat);

System.out.println(map);

Execution result


{key1=AAA}
{key1=AAABBB}

Why did you look at merge

This time, I investigated the behavior of Map # merge in detail. What is new in Java 8 is that the operation of Map <String, List <String >> adds a value to List when a key exists. I wondered if I could make it smarter. Specifically, I implemented it as follows.

Java8


Map<String, List<String>> map = new HashMap<String, List<String>>();

map.put("key1", new ArrayList<String>(Arrays.asList("AAA")));
System.out.println(map);

//If key1 exists"CCC"To List, if it doesn't exist"BBB"Add a List with the element
map.merge("key1", new ArrayList<String>(Arrays.asList("BBB")),
		(v1, v2) -> {
	v1.add("CCC");
	return v1;
});

System.out.println(map);

Execution result


{key1=[AAA]}
{key1=[AAA, CCC]}

Before Java 7, it looks like the following.

Up to Java 7


Map<String, List<String>> map = new HashMap<String, List<String>>();

map.put("key1", new ArrayList<String>(Arrays.asList("AAA")));
System.out.println(map);

if (map.containsKey("key1")) {
	//If key1 exists"CCC"To List
	map.get("key1").add("CCC");
} else {
	//If key1 does not exist"BBB"Add a List with the element
	map.put("key1", new ArrayList<String>(Arrays.asList("BBB")));
}

System.out.println(map);

Execution result


{key1=[AAA]}
{key1=[AAA, CCC]}

In this example, neither is much different (; ^ ω ^) However, with Java 8, I felt refreshed because I could eliminate the if-else statement.

So, is Map # merge useful when you want to make some changes to a value that already exists in the Map or when you want to make your code cleaner? The latter is also the reason for using lambda expressions and Streams, not just this method.

bonus

As an aside, if you return null in the remapping function, the key will be deleted.

Try erasing the key


Map<String, String> map = new HashMap<String, String>();
map.put("key1", "AAA");

System.out.println(map);

map.merge("key1", "BBB", 
	(v1, v2) -> {
		return null;
	});

System.out.println(map);

Execution result


{key1=AAA}
{}

Let's play with Java 8 a little more ^^

Recommended Posts

[Java] Map # merge is hard to understand.
[Java] How to use Map
[Java] How to use Map
How to use Java Map
Java thread to understand loosely
[Java] Code that is hard to notice but terribly slow
[Java] Convert 1-to-N List to Map
JAVA (Map)
Java reference to understand in the figure
Java Realm is difficult to handle 3 points
What is java
Java compilation error Unable to map to encoding windows-31j
What is Java <>?
What is Java
[Java] Map comparison
[Java] Introduction to Java
Introduction to java
[Java 8+] Merge maps
Understand java constructor
When the hover of Eclipse is hard to see
Java classes and instances to understand in the figure
How to loop Java Map (for Each / extended for statement)
I want to get along with Map [Java beginner]
Changes from Java 8 to Java 11
Sum from Java_1 to 100
How to use Map
How to use map
[Java] Stream API / map
[Java] Connect to MySQL
Understand Java 8 lambda expressions
What is Java Encapsulation?
Kotlin's improvements to Java
Enum reverse map Java
Merge Java Word documents
From Java to Ruby !!
Java bidirectional map library
What is Java technology?
What is Java API-java
Introduction to java command
[Java] What is flatMap?
[Java] What is JavaBeans?
[Java] What is ArrayList?
How to use Map
List processing to understand with pictures --java8 stream / javaslang --bonus
Road to Java Engineer Part2 What kind of language is Java?
For Java beginners: List, Map, Iterator / Array ... How to convert?
[Java] UTF-8 (with BOM) is converted to 0xFFFD (REPLACEMENT CHARACTER)