Search code examples
java

Convert List<String> to Map<String, Integer>


I have a following list of teams with their score:

List<String> teams = Arrays.asList("Dortmund 8", "Bayern 10", "Madrid 9", "Bayern 2");

I want to convert it to map like Map<String, Integer>, so the String is the team and the score is Integer ("Dortmund", 8). Is it possible to make it without stream or better with stream? The example of converting will be much appreciated.


Solution

  • for (String s : teams)
    { 
       String[] kv = s.split(" "); 
       int val = Integer.parseInt(kv[1]);
    
       map.put(kv[0], map.get(kv[0])==null ? val : map.get(kv[0]) + val);
    }
    
    //Map -  { Dortmund - 8 | Bayern - 12 | Madrid - 9 }
    

    As an alternative to map.put, @Okx comment offers a cleaner approach to do this, using merge().

    Internally, works like this for the HashMap implementation. If no value is found for the key, the value will be stored. If the key exists, it will apply the function passed as a third argument.

    @Override
    public V merge(K key, V value,
                 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
      if (value == null)
          throw new NullPointerException();
      if (remappingFunction == null)
          throw new NullPointerException();
      int hash = hash(key);
      Node<K,V>[] tab; Node<K,V> first; int n, i;
      int binCount = 0;
      TreeNode<K,V> t = null;
      Node<K,V> old = null;
      if (size > threshold || (tab = table) == null ||
          (n = tab.length) == 0)
          n = (tab = resize()).length;
      if ((first = tab[i = (n - 1) & hash]) != null) {
          if (first instanceof TreeNode)
              old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key);
          else {
              Node<K,V> e = first; K k;
              do {
                  if (e.hash == hash &&
                      ((k = e.key) == key || (key != null && key.equals(k)))) {
                      old = e;
                      break;
                  }
                  ++binCount;
              } while ((e = e.next) != null);
          }
      }
      if (old != null) {
          V v;
          if (old.value != null)
              v = remappingFunction.apply(old.value, value);
          else
              v = value;
          if (v != null) {
              old.value = v;
              afterNodeAccess(old);
          }
          else
              removeNode(hash, key, null, false, true);
          return v;
      }
      if (value != null) {
          if (t != null)
              t.putTreeVal(this, tab, hash, key, value);
          else {
              tab[i] = newNode(hash, key, value, first);
              if (binCount >= TREEIFY_THRESHOLD - 1)
                  treeifyBin(tab, hash);
          }
          ++modCount;
          ++size;
          afterNodeInsertion(true);
      }
      return value;
    }
    
       
    

    So it will essentially follow the same logic, but with a cleaner syntax:

    for (String s : teams)
    { 
       String[] kv = s.split(" "); 
       int val = Integer.parseInt(kv[1]);
       map.merge(kv[0], val, Integer::sum);
    }
    

    So appreciated, Okx, for sharing this.