Java create nested map

Java Nested Map with Examples

Learn to work with Nested HashMap in Java. From creating, removing, and iterating the elements, we will also see the practical use-cases where we can use nested maps.

HashMap class extends AbstractMap class and implements the Map interface. It holds entry objects i.e. key-value pairs. The keys or the values are of Object types.

A nested HashMap is Map inside a Map. The only difference between a HashMap and a nested HashMap is:

  • For HashMap , the key or the value can be of any type (object).
  • For Nested HashMap , the key can be of any type (object), but the value is another HashMap object only.

Notice the nested HashMap created below; we create a HashMap having ‘ String ‘ as the key and another ‘ HashMap ‘ as the value for this map and this is what we call as Nested HashMap.

// Creating Nested HashMap Map> nestedMap = new HashMap<>();

2. When to use a Nested Map?

We use nested maps when we need nested objects i.e. objects inside an object. Let’s take an example of JSON data structure where we have nested objects inside the other objects.

Nested Maps are hard to scale, making it difficult to read the code (code readability). More importantly, Maps in Java tend to consume a lot of memory. Populating a Map with even more Maps will only aggravate the memory consumption issue. So we have to be careful while using it and it will be used in special scenarios where it is actually required.

Читайте также:  Java thread new thread example

3. Working with Nested HashMap

To create a nested map, we will first have to create a normal HashMap, just the value of this map will be another HashMap.

3.1. Creating Nested Map using Map.put()

We can use Map interface put() method for adding elements in the outer as well as inner HashMap.

Map> employeeMap = new HashMap<>(); Map addressMap = new HashMap<>(); addressMap.put("Permanent", "Florida"); addressMap.put("Postal", "Canada"); employeeMap.put("Alex", addressMap);

3.2. Creating Nested Map using Streams

We can use stream api to create nested maps using Collectors.toMap() method. In following example, we are creating a ‘ Student ‘ class having ‘ studentId ‘ and other fields.

We have a list of Student objects, and from this list, we are creating a nested Map having key as ‘studentId’ and value as another Map with key as studentName and value as course .

// Creating Nested Map List studentList = List.of( new Student(1, "A", "Course1"), new Student(2, "B", "Course2"), new Student(3, "C", "Course3")); Map> studentNestedMap = studentList.stream() .collect(Collectors.groupingBy(s -> s.getStudentId(), Collectors.toMap(Student::getStudentName, Student::getCourse)));

3.3. Adding Element to Nested Map

We can add new elements to an existing nested Map by first retrieving the nested map from the outer map and then using the put() method to add the new elements to the inner map.

Map> employeeMap = new HashMap<>(); //Adding another address for Alex employeeMap.get("Alex").put("Hideout", "UAE");

3.4. Removing Element from Nested Map

To remove elements from nested HashMap, invoke remove() similar to the previous example.

Map> employeeMap = new HashMap<>(); //Hideout has been exposed so removing it employeeMap.get("Alex").remove("Hideout");

3.5. Iterating over Nested HashMap

We can iterate over a nested map just like we will iterate over a normal HashMap.

Map> employeeMap = new HashMap<>(); for (Map.Entry> empMap : employeeMap.entrySet()) < MapaddMap = empMap.getValue(); // Iterate InnerMap for (Map.Entry addressSet : addMap.entrySet()) < System.out.println(addressSet.getKey() + " :: " + addressSet.getValue()); >>

We have learned the Nested Maps and how to create them and add, remove and iterate over the elements. We have also seen where we can use the nested maps.

Источник

Creating Nested Maps by Splitting Strings in Java 8

One possible solution involves using a loop to add the key value pairs to the map. To prevent issues with malformed cookie strings, an «if» statement can be used. Alternatively, a stream can be used instead of a loop. To avoid overriding values, @WJS suggests using «toMap» instead of «groupingBy». Finally, the map can be collected by grouping by the first subitem and creating an inner map with the second value as the key and the last value as the value.

Java 8 Split String and Create Map inside Map

There exists a string that resembles the following format: 101-1-5,101-2-4,102-1-5,102-2-5,102-3-5,103-1-4 .

I am interested in including this within the Map> framework.

How to do this using Java 8 stream?

I attempted to utilize standard Java and found that it functions appropriately.

public class Util < public static void main(String[] args) < String samp = "101-1-5,101-2-4,102-1-5,102-2-5,102-3-5,103-1-4"; Map> m1 = new HashMap<>(); Map m2 = null; String[] items = samp.split(","); for(int i=0; i(); > m2.put(subitem[1], subitem[2]); m1.put(subitem[0], m2); > System.out.println(m1); > > 

The subsequent code snippet may be employed for this purpose.

Map> result = Arrays.stream(samp.split(",")) .map(i -> i.split("-")) .collect(Collectors.groupingBy(a -> a[0], Collectors.toMap(a -> a[1], a -> a[2]))); 

Initially, a stream of items is generated, which is then transformed into a stream of arrays holding the subitems. Eventually, the first subitem is grouped by, and an inner map is generated with the second value serving as the key and the final value as the corresponding value.

Map> map = Arrays.stream(samp.split(",")) .map(s -> s.split("-")) .collect(Collectors.toMap( o -> o[0], o -> Map.of(o[1], o[2]), (m1, m2) -> Stream.concat(m1.entrySet().stream(), m2.entrySet().stream()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)))); 

If you are using Java 9, then Map.of is applicable. However, in case you are working with Java 8, you can opt for AbstractMap.SimpleEntry .

Samuel’s response, on the other hand, is more effective and succinct.

Pattern to split string and store in HashMap Java 8, String[] keyValues = currentString.split(«=», 2); String[] keys = keyValues[0].split(«-«);

Split String into Map using Java Streams

My objective is to divide the given String and save it in a Map.

String = "key_a:\r\n\r\nkey_b:\r\n\r\nkey_c:" 

The pairs within the string may contain line breaks. Multiple values separated by , , starting with < and ending with >, can be assigned to a single key.

The given string requires conversion into Map> .

The map’s layout must resemble this.

At present, I have the algorithm to separate the key-value-pairs, but I am unsure about the technique to divide the values, eliminate the brackets, and associate the characteristics.

String strBody = "key_a:\r\n\r\nkey_b:\r\n\r\nkey_c:" Map> map = Pattern.compile("\\r?\\n") .splitAsStream(strBody) .map(s -> s.split(":")) //. logic for splitting values apart from each other, removing <> brackets and storing it in the map ) 

To group elements in arrays with two values, apply a filter and then use Collectors.groupingBy. Check out additional examples of mapping and Map and groupingBy here.

 Map> map = Pattern.compile("\\r?\\n") .splitAsStream(strBody) .map(s -> s.split(":")) .filter(arr -> arr.length == 2) .collect(Collectors.groupingBy(arr -> arr[0], Collectors.mapping(arr -> arr[1].replaceAll("[<>]", ""), Collectors.toList()))); 

To avoid empty entries, you should split the input by the two separators provided. Otherwise, you will need to filter out these empty entries.

Before processing the string in the stream, it is recommended to eliminate the angle brackets. After that, the only task left is to collect the data.

Map map = Pattern.compile("\\r?\\n\\r?\\n") .splitAsStream(strBody.replaceAll("[<>]","")) .map(s -> s.split(":")) .collect(Collectors.toMap(e -> e[0], e-> e[1])); 

Another method that divides the value list is also available.

Map> result = Pattern.compile("[\\r\\n]+") .splitAsStream(strBody) .map(s -> s.split(":")) .map(arr -> new AbstractMap.SimpleEntry<>( arr[0], Arrays.asList(arr[1].replaceAll("[<>]", "").split("\\s*,\\s")))) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
String strBody = "key_a:\r\n\r\nkey_b:\r\n\r\nkey_c:"; Map> result = Arrays.stream(strBody.split("\\R\\R")) .map(e -> e.split(":", 2)) .collect(Collectors.toMap(a -> a[0], a -> List.of(a[1].replaceAll("^<|>$", "").split("\\s,\\s*")))); System.out.println(result); 

Map to String Conversion in Java, Convert a Map to a String Using Java Streams To perform conversion using streams, we first need to create a stream out of the available Map

Split string into parts in java to put it in a map

My goal is to extract all the values from a given string and organize them into a map using the following approach:

I possess a string that appears as follows:

String cookies = "i=lol;haha=noice;df3=ddtb;" 

So far I have been trying this out:

final Map map = new HashMap<>(); map.put(cookies.split(";")[0].split("=")[0], cookies.split(";")[0].split("=")[1]); 

Is there a way to simplify the process of inputting a long and unappealing value? Perhaps by using regex or a loop?

One possible approach is to employ a loop to traverse through the key-value pairs and add them to the map.

String[] cookieArr = cookies.split(";"); for(String cookieString : cookieArr) < String[] pair = cookieString.split("="); if(pair.length < 2)< continue; >map.put(pair[0], pair[1]); > 

The purpose of the "if" statement is to avoid any arrayindexoutofbounds errors in case the cookie string is not in a proper format.

Another option could be to utilize a stream.

Arrays.stream(cookies.split(";")).forEach(cookieStr -> map.put(cookieStr.split("=")[0], cookieStr.split("=")[1])); 

In the comment, @WJS suggested using map.putIfAbsent(key, vlaue) instead of map.put(key, value) to avoid value overriding. However, for cookies, overwriting the old value with the new may be the intended behavior.

Here's one way to do it, assuming your format remains consistent.

  • Initially, it divides every key/value pair using the separator ";".
  • Dividing the equal sign into a key and a value.
  • and adds to map.
  • In case of duplicate keys, the merge lambda (a, b)-> b can be used to obtain the latest value instead of the first one encountered, which takes precedence.
String cookies = "i=lol;haha=noice;df3=ddtb"; Map map = Arrays.stream(cookies.split(";")) .map(str -> str.split("=")).collect(Collectors .toMap(a -> a[0], a->a[1], (a, b) -> a)); map.entrySet().forEach(System.out::println); 

Источник

Оцените статью