将参数数组转换为HashMap

时间:2014-12-19 09:16:25

标签: java algorithm collections

我有一个字符串数组,就像:

String [] paramEnv = {"key1=value1","key2=value2","key2=value2"};

现在我需要将其转换为HashMap。

我已经为它编写了两种方法,我想知道哪种方法在效率方面更好。

方法1:

String param = "";
String paramName = "";
String paramValue = "";
if ((null != paramEnv) && (paramEnv.length > 0)) {
        for (int i = 0; i < paramEnv.length; i++) {
            param = paramEnv[i];
            int indexOfEqualTo = param.indexOf("=");
            paramName = param.substring(0, indexOfEqualTo);
            paramValue = param.substring(indexOfEqualTo + 1);
            hmKeyValFromParamEnv.put(paramName, paramValue);
        }
    }
    return hmKeyValFromParamEnv;

方法2:

String param = "";
String paramName = "";
String paramValue = "";
if ((null != paramEnv) && (paramEnv.length > 0)) {
        for (int i = 0; i < paramEnv.length; i++) {
            param = paramEnv[i];
            paramName = (param.split("="))[0];
            paramValue = (param.split("="))[1];
            hmKeyValFromParamEnv.put(paramName, paramValue);
        }
    }
    return hmKeyValFromParamEnv;

如果有任何更好的实施,请告诉我。

3 个答案:

答案 0 :(得分:2)

如果可以使用Java 8

public class ArrayToMap {

    public static void main(String[] args) {
        String[] arr = new String[]{"key1=value1","key2=value2"};

    Arrays.stream(arr)
            .map(s -> s.split("="))
            .collect(Collectors.toMap(sa -> sa[0], sb -> sb[1], (v1, v2)->v1));
    }
}
  • 从数组
  • 制作流
  • 将每个数组元素映射到两个元素数组(拆分)
  • 使用自定义合并功能将其收集到地图

//编辑:

添加重复消除。这只是一个例子。你应该制定自己的策略来消除重复(如果你需要一些具体的)。

//编辑2: @ZouZou发表评论后,将impl改为使用自定义合并函数

//编辑3: 如果你不能使用Java 8,那么使用guava:

class KeyEntry<K, V> implements Map.Entry<K, V> {
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof KeyEntry)) {
            return false;
        }

        KeyEntry keyEntry = (KeyEntry) o;

        if (!key.equals(keyEntry.key)) {
            return false;
        }

        return true;
    }

    @Override
    public String toString() {
        return "{\"KeyEntry\":{" +
                "\"key\": \"" + key + "\"" +
                ", \"value\": \"" + value + "\"" +
                "}}";
    }

    @Override
    public int hashCode() {
        return key.hashCode();
    }

    KeyEntry(K key, V value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public K getKey() {
        return key;
    }

    @Override
    public V getValue() {
        return value;
    }

    @Override
    public V setValue(V value) {
        throw new UnsupportedOperationException("NO!");
    }

    private final K key;
    private final V value;


}

因为常见Entry impl使用equals中的键和值,我们需要自定义类。

然后我们可以创建类似的东西:

    Map<String, String> m = new HashMap<>();
    ImmutableSet<Map.Entry<String, String>> uniqueKey = FluentIterable.from(new ArrayList<String>(Arrays.asList(arr)))
            .transform(new Function<String, Map.Entry<String, String>>() {
                @Override
                public Map.Entry<String, String> apply(String s) {
                    String[] splited = s.split("=");
                    return new KeyEntry(splited[0], splited[1]) {
                    };
                }
            }).toSet();

    for (Map.Entry<String, String> s : uniqueKey) {
        m.put(s.getKey(), s.getValue());
        System.out.println(s);
    }
  • 将每个元素转换为KeyEntry
  • make Set
  • 重写为Map

答案 1 :(得分:0)

两者都具有O(n)复杂性。要在速度上有显着差异,您需要非常大的paramEnv数组。

正如评论者指出的那样,你可以通过在数组中存储split的两个参数然后将它们放入map中来稍微优化它。通过这样做你是否会得到任何显着的速度提升还不是很清楚(我的猜测是你可能不会获得那么快的速度)。

答案 2 :(得分:0)

我会选择你的第一个实现,因为子字符串会更快更有效(你只需要查看字符,直到找到等于符号),而不是基于模式匹配和描述here的分割。