Search code examples
javaguava

Java guava Splitter failing when there are duplicate keys


How we can handle duplicate keys while using java guava Splitter function. Here is the sample code which is encountering the following issue. Is there a better way to handle this issue.

String fieldSplit = " ";
String valueSplit = "=";
String message = "ip=1.2.9.0 error=NA ip=1.2.9.0";
Map<String, String> parserMap = Splitter.on(fieldSplit).omitEmptyStrings().withKeyValueSeparator(valueSplit).split(message);

Exception in thread "kv-plugin-ac801a38-66f1-4ffe-86ca-f9eb6c823842-StreamThread-1" org.apache.kafka.streams.errors.StreamsException: Exception caught in process. taskId=0_0, processor=KSTREAM-SOURCE-0000000000, topic=kv-input, partition=0, offset=22, stacktrace=java.lang.IllegalArgumentException: Duplicate key [ip] found.

Im getting the above error. Can somebody suggest a better way to handle this. Since im new to java.


Solution

  • Depends on what you want to do with the duplicate keys. Map<String, String> is a key value storage that can have only unique keys and only one value.

    If you want to store all those values you would need something like Map<String, List<String> or Guava Multimap.

    In this case you cannot do this with the Splitter as it cannot handle duplicate keys. You would need to write the logic by yourself.

    String fieldSplit = " ";
    String valueSplit = "=";
    String message = "ip=1.2.9.0 error=NA ip=1.2.9.0";
    
    Map<String, List<String>> parserMap = new HashMap<>();
    
    for (String part : message.split(" ")) {
      String[] subparts = part.split("=", 2);
      if (!parserMap.contains(subparts[0])) {
         parserMap.put(subparts[0], new ArrayList<>());
      }
      parserMap.get(subparts[0]).add(subparts[1]);
    }
    
    

    If you want to omit those duplicate entries you can still use the Map<String, String> with something like this.

    
    Map<String, String> parserMap = new HashMap<>();
    
    for (String part : message.split(" ")) {
      String[] subparts = part.split("=", 2);
      if (!parserMap.contains(subparts[0])) {
         parserMap.put(subparts[0], subparts[1]);
      }
    }