This is the 18th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

🤞 personal home page: @Qingcheng sequence member Stone 🤞 fan benefits: plus one to one fan group to answer questions, get free rich resume template, improve learning materials, do a good job in the new era of volume king!

The great Java 18 is coming soon, and we may not be familiar with the core usage of Lambda in Java 8. In this article, we will share some tips on how to use Map during the development process of Stream technology. After reading this article, you will have a new understanding of Stream.

Initialize a Map gracefully

Before moving on, think about how you could initialize a Map with initial values without using a three-way package such as Apache Common. The code looks something like this.

final HashMap<String, String> maps = new HashMap<>();
maps.put("key1"."value1");
maps.put("key2"."value2");
Copy the code

The above method does initialize the Map, but the biggest problem is that we may need to change many lines to put the key-value pairs, which is very verbose. To keep the code clean and take advantage of Java 8, we can actually initialize the Map using stream as shown below.

final HashMap<String, String> maps = Stream.of(new Object[][]{{"key1"."value1"}})
    .collect(Collectors.toMap(data -> (String) data[0], data -> (String) data[1]));
Copy the code

A single line of code to initialize a Map would be much more elegant. If you’ve ever used a Jooq Tuple, you’ve found that using a Tuple is much more elegant and allows you to do amazing things.

B: List to Map gracefully

In the daily development process, in order to construct a specific data format for the front end, it is inevitable for the partners at the back end to convert List data into Map data, so I would like to ask how you will accomplish this problem? In general, it is necessary to complete the transformation of data through traversal. But Java 8 has Stream, and we can do something interesting with it.

Suppose we have a class Product, as shown in the following code.

@Getter
@Setter
@ToString
@Builder
class Product{
    private Long id;
    private String category;
    private String name;
}
Copy the code

We now have data in the List format.

static List<Product> getList(a){
    final List<Product> productList = new ArrayList<>(100);
    for(int i =1; i<=100; i++){ productList.add(Product.builder() .id((long) i)
            .name("name"+i)
            .category("category"+i%9)
            .build());
    }
    return productList;
}
Copy the code

Now we want to get the Map format data with id as key and name as value, as follows.

Map<Long, String> map = productList.stream().collect(Collectors.toMap(Product::getId, Product::getName));
Copy the code

If you want to obtain Map format data with id as key and product as value, the code is as follows.

Map<Long, Product> map = productList.stream().collect(Collectors.toMap(Product::getId, data -> data));
Copy the code

If you want to obtain Map data with category as key and name as value, keys may conflict. How to resolve this problem? You need to pass in the key conflict resolution policy, and the code is as follows.

In case of a conflict, keep the existing data, You can customize it based on services. Map<String, String> Map = productList.stream().collect(Collectors. ToMap (Product::getCategory, Product::getName, (existing, replacement) -> existing));Copy the code

To get a thread-safe Map, you need to pass in a Supplier

mapSupplier.

# ConcurrentHashMap ConcurrentHashMap<String, String> map = productList.stream().collect(Collectors.toMap(Product::getCategory, Product::getName, (existing, replacement) -> existing, ConcurrentHashMap::new));
Copy the code

Boy, haven’t you seen enough? Click on the details of the stone, casually have a look, maybe there is a surprise? Welcome to support the likes/attention/comments, your support is my biggest motivation, thank you!