Converting string arrays into Map

前端 未结 5 610
没有蜡笔的小新
没有蜡笔的小新 2020-11-29 13:46

I have two string arrays keys and values

String[] keys = {a,b,c,d};

String[] values = {1,2,3,4};

What is the fastest way to convert them i

相关标签:
5条回答
  • 2020-11-29 13:51

    Convert two String arrays to Map in Java

    import java.util.HashMap;
     public static void main(String[] args){
        String[] keys= {"a", "b", "c"};
        int[] vals= {1, 2, 3};
        HashMap<String, Integer> hash= new HashMap<String, Integer>();
    
        for(int i= 0; i < keys.length; i++){
          hash.put(keys[i], vals[i]);
        }
     }
    

    Check this LINK for more solutions in different programming languages

    Note : The keys should be unique..

    0 讨论(0)
  • 2020-11-29 13:55

    IMHO, it's highly unlikely that you will find a utility like that.

    But, even if you find one chances are really low that it will provide any performance gain. Because, I think you won't able to do it without iterate through all the elements in both the arrays.

    One thing I can suggest is (only if your arrays have a huge number of elements) that you can specify the capacity of the map while instantiating it to reduce overhead of resizing while you put entries into it.

    Map<String, String> map = new HashMap<String, String>(keys.length);
    //put keys and values into map ...
    
    0 讨论(0)
  • 2020-11-29 14:00

    I purpose to you two very simple implementations. One with stream Api of Java 8, one without.

    Java < 8 (without stream api)

    if(keys.length != values.length) { 
        throw new IllegalArgumentException("Keys and Values need to have the same length."); 
    }
    Map<String,String> map = new HashMap<>();
    for (int i = 0; i < keys.length; i++) {
        map.put(keys[i], values[i]);
    }
    

    Java > 8 (with stream api)

    if(keys.length != values.length) { 
        throw new IllegalArgumentException("Keys and Values need to have the same length."); 
    }
    Map<String,String> map = IntStream.range(0, keys.length).boxed()
        .collect(Collectors.toMap(i -> keys[i], i -> values[i]));
    
    0 讨论(0)
  • 2020-11-29 14:03

    Constant time lookup from the start

    If you are looking for a Map that retrieves the value associated with a key in constant time (meaning without having to look at most values), then you cannot do much faster, because the arrays need to be processed.

    However, you can use a utility already written that way : com.google.common.collect.Maps.uniqueIndex

    Instantaneous conversion, Linear time lookup

    If you are ok with a Map that searches the array for the key every time, then you can create the Map instantly using your two arrays, by defining a new class that implements the Map interface :

    class TwoArrayMap implements Map<String, String> {
    
       private final String[] keys;
       private final String[] values;
       // If you want to enable to add more key value pairs to your map, and
       // want to make the process faster, you could use ArrayLists instead of arrays
    
       public TwoArrayMap(String[] array1, String[] array2){
           if(array1 == null || array2 == null || array2.length < array1.length)
              throw new IllegalArgumentException();
           keys = array1;
           values = array2;
           // Alternatively, you could want to clone the arrays, to 
           // make sure they are not modified, using array1.clone(), etc
       }
    
       public String get(String key){
    
           for(int i=0; i<keys.length; i++)
                 if(key == null && key == null || key != null && key.equals(k) )
                    return values[i];
           return null;                     
       }
    
       public String put(String key, String Value) throws OperationNotSupportedException {
            throw new OperationNotSupportedException();
            // alternatively, you could resize the arrays and add a new key, or use an ArrayList
       }
    
    }
    
    Map<String, String> myMap = new TwoArrayMap(keys, values);
    


    Lazy conversion, constant time lookup after conversion

    Another approach would be to do it "lazily", meaning modify the above class, so that it keeps a reference to a HashMap internally, and fills it only when it is looking up elements :

    class TwoArrayMap implements Map<String, String> {
    
       private final Map<String, String> hashmap;
       private int maxIndexAlreadyTransferred = -1;
    
       private final String[] keys;
       private final String[] values;
    
       public TwoArrayMap(String[] array1, String[] array2){
           if(array1 == null || array2 == null || array2.length < array1.length)
              throw new IllegalArgumentException();
           hashmap = new HashMap<>();
           keys = array1;
           values = array2;
           // Alternatively, you could want to clone the arrays, to 
           // make sure they are not modified, using array1.clone(), etc
       }
    
       public String get(String key){
    
           if(hashmap.containsKey(key))
                return hashmap.get(key);
    
           String k, value;
           while( maxIndexAlreadyTransferred + 1 < keys.length ){
                 k = keys[ maxIndexAlreadyTransferred + 1 ];
                 value = values[ maxIndexAlreadyTransferred +1 ];
                 if(!hashmap.containsKey(k))
                     hashmap.put( k, value );
                 maxIndexAlreadyTransferred++;
                 if(key == null && k == null || key != null && key.equals(k) )
                    return value;
           }
           return null;                     
       }
    
       public String put(String key, String Value) {
            hashmap.put(key, value);
       }
    
    }
    

    This solution would mean :

    • an instantaneous creation of your new object
    • linear time lookup for the first times you will query it, until everything is transferred
    • constant time lookup after that, behaving as a hash table
    0 讨论(0)
  • 2020-11-29 14:15

    Faster than this?

    Map<String,String> map = new HashMap<>();
    
    if(keys.length == values.length){
        for(int index = 0; index < keys.length; index++){
            map.put(keys[index], values[index]);
        }
    }
    
    0 讨论(0)
提交回复
热议问题