Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add values in duplicated key Map in Java 8

I want to add values in duplicated key Map in Java 8.

As an example:

For example: if strArr is ["B:-1", "A:1", "B:3", "A:5"] then my program should return the string A:6,B:2.

My final output string should return the keys in alphabetical order. Exclude keys that have a value of 0 after being summed up.

Input: new String[] {"X:-1", "Y:1", "X:-4", "B:3", "X:5"}

Output: B:3,Y:1

Input: new String[] {"Z:0", "A:-1"}

Output: A:-1

Tried code:

public static String Output(String[] strArr) {
       //strArr = new String[] {"X:-1", "Y:1", "X:-4", "B:3", "X:5"};
        Map<String, Double> kvs =
                Arrays.asList(strArr)
                    .stream()
                    .map(elem -> elem.split(":"))
                    .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1])));
        
        kvs.entrySet().forEach(entry->{
            System.out.println(entry.getKey() + " " + entry.getValue());  
         });
        
        return strArr[0];
      }

Error:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key -1.0

How can I fix this?

like image 227
jaxij Avatar asked Feb 06 '21 06:02

jaxij


People also ask

Can we add duplicate values in map?

Map doesn't allow duplicate keys, but it allows duplicate values. HashMap and LinkedHashMap allows null keys and null values but TreeMap doesn't allow any null key or value. Map can't be traversed so you need to convert it into Set using keySet() or entrySet() method.

Can we add duplicate values in HashMap in Java?

Duplicates: HashSet doesn't allow duplicate values. HashMap stores key, value pairs and it does not allow duplicate keys.

Can a map have multiple values for same key Java?

If this is an application requirement, the three best ways to solve the 'multiple values per key in a map in Java' problem are: Stick with the standard APIs and add a collection class like a 'Vector' or 'ArrayList' to your map or set. Use the MultiMap and MultiValueMap classes from the Apache Commons library.

What happens if we try to add value with duplicate key in HashMap?

If you try to insert the duplicate key, it will replace the element of the corresponding key. HashMap is similar to HashTable, but it is unsynchronized. It allows to store the null keys as well, but there should be only one null key object and there can be any number of null values.

How to get duplicate keys from a map?

Map does not supports duplicate keys. you can use collection as value against same key. Because if the map previously contained a mapping for the key, the old value is replaced by the specified value. you can use something like this.

What happens when we try to add a duplicate key into HashMap?

What happens when we try to add a duplicate key into a HashMap object in java? The HashMap is a class that implements the Map interface. It is based on the Hash table. It allows null values and null keys. You can store key-value pairs in the HashMap object.

Can a Java Map handle multiple values for a single key?

Java has several implementations of the interface Map, each one with its own particularities. However, none of the existing Java core Map implementations allow a Map to handle multiple values for a single key.

How to convert list to map in Java 8?

1. Introduction In this article, You'll explore and learn how to convert List to Map in Java 8. First, Let us convert List into Map. Next, Convert List of user-defined (custom) objects to Map and handling with the duplicate keys. 2. Collectors.toMap () Method: List<V> into Map<K, V>


3 Answers

You should declare a merging strategy in the first stream:

.collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1]), Double::sum));

and then filtered Map by zero value:

  .filter(s-> s.getValue() != 0)

for sorting by key use:

   .sorted(Map.Entry.comparingByKey())

result code:

   String [] strArr = new String[] {"X:-1", "Y:1", "X:-4", "B:3", "X:5"};
    Map<String, Double> kvs =
            Arrays.asList(strArr)
                    .stream()
                    .map(elem -> elem.split(":"))
                    .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1]), Double::sum));

    kvs.entrySet().stream()
            .filter(s-> s.getValue() != 0)
            .sorted(Map.Entry.comparingByKey())
            .forEach(entry->{
        System.out.println(entry.getKey() + " " + entry.getValue());w
    });
like image 138
Dmitrii B Avatar answered Oct 26 '22 10:10

Dmitrii B


It's working for me , I used Integer instead of double and summaringInt() function for sum values with same key:

        String[] strArr = new String[] { "X:-1", "Y:1", "X:-4", "B:3", "X:5" };

    Map<String, IntSummaryStatistics> collect = Arrays.asList(strArr)
        .stream()
        .map(elem -> elem.split(":"))
        .collect(Collectors.groupingBy(e -> e[0], Collectors.summarizingInt(e -> Integer.parseInt(e[1]))));

    System.out.println("Result:");

    collect.entrySet().stream()
        .filter(e -> e.getValue().getSum() != 0)
        .sorted(Map.Entry.comparingByKey())
        .forEach(e -> System.out.println("Key : " + e.getKey() + ", Value : " + e.getValue().getSum()));
like image 4
tomeszmh Avatar answered Oct 26 '22 10:10

tomeszmh


It is also possible to use Collectors.groupingBy + Collectors.summingDouble to build a sorted kvs map by collecting to TreeMap:

String [] strArr = new String[] {"X:-1", "Y:1", "X:-4", "B:3", "X:5"};
Map<String, Double> kvs = Arrays.stream(strArr)
        .map(elem -> elem.split(":"))
        .collect(Collectors.groupingBy(
            e -> e[0], 
            TreeMap::new, // sort by key
            Collectors.summingDouble(e -> Double.parseDouble(e[1]))
        ));
System.out.println(kvs);  // entries with 0 value yet to be removed
// output
// {B=3.0, X=0.0, Y=1.0}

If it is required just to print the map in the mentioned format without 0 values, it may be done like this:

System.out.println(
    kvs.entrySet().stream()
        .filter(e -> e.getValue() != 0)
        .map(e -> new StringBuilder(e.getKey()).append(':').append(e.getValue().intValue()) )
        .collect(Collectors.joining(","))
);
// output
// B:3,Y:1

If 0 values need to be removed from kvs, a removeIf may be applied to its entry set:

kvs.entrySet().removeIf(e -> e.getValue() == 0);
System.out.println(kvs);
// output
// {B=3.0, Y=1.0}
like image 4
Nowhere Man Avatar answered Oct 26 '22 12:10

Nowhere Man