1

您好我试图通过使用普通数组存储 2 个键值来避免创建对象,但它似乎不起作用。

我可以知道是否有任何解决方案可以避免创建一个对象,或者我只是太努力了?

忘记添加:

1)我知道为什么它不起作用......如果我不这样做,我将不会为 key 实现 equals() 和 hashcode()。

2)基本上我试图在检索密钥时避免创建 1 个对象。通常在服务类中会有一个方法

public void get(String key1, String key2){
       return keyMap.get(new Key(key1,key2)); <>>avoiding the new Key()
}

断线

import java.util.HashMap;
import java.util.Map;


public class ArrayMap {

    /**
     * @param args
     */
    public static void main(String[] args) {

        /*start A  Possible to get this to work? */
        Map<String[], String> arrMap = new HashMap<>();
        arrMap.put(new String[] { "hello", "hi" }, "hello motto");
        System.out.println(arrMap);
        System.out.println(arrMap.get(new String[] { "hello", "hi" })); // print
                                                                        // null
         /* end of A */

        /*Start of B: Reason: to avoid this */
        Map<Key, String> keyMap = new HashMap<Key, String>();
        keyMap.put(new Key("hello", "hi"), "hello motto"); // I wish to avoid one object creation 

        System.out.println(keyMap.get(new Key("hello", "hi"))); // print
                                                                // "hello motto"
        /*End of B: Reason: to avoid this */
    }
}

class Key {
    private final String key1;
    private final String key2;

    public Key(String key1, String key2) {
        this.key1 = key1;
        this.key2 = key2;
    }

    public String getKey1() {
        return key1;
    }

    public String getKey2() {
        return key2;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((key1 == null) ? 0 : key1.hashCode());
        result = prime * result + ((key2 == null) ? 0 : key2.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Key other = (Key) obj;
        if (key1 == null) {
            if (other.key1 != null)
                return false;
        } else if (!key1.equals(other.key1))
            return false;
        if (key2 == null) {
            if (other.key2 != null)
                return false;
        } else if (!key2.equals(other.key2))
            return false;
        return true;
    }
}
4

4 回答 4

4

这种方法有几个问题。

1. 您不能覆盖数组的equals()/hashcode()方法- 这是一个问题,因为HashMap无法正确确定它是否查找了正确的键。

2. 每次要创建密钥时,您仍在创建新对象。数组是对象——每次都创建一个新的,你什么也没有保存。不妨使用您的原始Key对象。

可能的解决方案

因此,我将假设您希望避免每次都创建新对象的原因是因为您将经常调用get(key)该对象HashMap。如果是这种情况,为什么不创建一个Key保留在ArrayMap对象内部的可变实例。每次您想键入两个Strings 时,只需将它们设置在您的可变Key实例中并使用该可变实例进行查找。然后,您不必在Key每次要查找一对Strings.

于 2013-03-13T14:54:39.777 回答
2

在这些行中

arrMap.put(new String[] { "hello", "hi" }, "hello motto");
System.out.println(arrMap);
System.out.println(arrMap.get(new String[] { "hello", "hi" })); // print
                                                                    // null

您使用 aString[]作为键。该对象没有自定义equals()方法,如您在Key类中可以比较内容的方法。因此,当您尝试map.get()传入一个新的String[](但具有相同的内容)时,它不会找到任何东西,因为它不是同一个对象。

你可能想做的是这个

String[] array = new String[] { "hello", "hi" };
arrMap.put(array , "hello motto");
System.out.println(arrMap);
System.out.println(arrMap.get(array)); // print hello motto

你真的不应该使用数组类型作为 Maps 的键。

于 2013-03-13T14:53:06.807 回答
2

我可以知道是否有任何解决方案可以避免创建一个对象,或者我只是太努力了?

如果你不确定你是否努力过头,那么你可能是。根据您提供给我们的信息,这看起来像是过早的优化。

几个相关的点:

  1. 对象的创建并不昂贵,特别是如果对象是短暂的。
  2. 确定一个软件的性能特征的唯一方法是通过分析。
于 2013-03-13T14:56:41.663 回答
1

在 java 中,array1.equals(array2) 仅当 array1 == array2 时,即它们在内存中是完全相同的实例。这会导致 Map 将它们视为单独的键。你最好使用你的 Key 类作为地图的键

于 2013-03-13T14:55:17.143 回答