通过避免对象创建来优化

时间:2013-03-13 14:49:32

标签: java

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

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

忘记了ADD:

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

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

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

BREAK LINE

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 个答案:

答案 0 :(得分:4)

这种方法存在一些问题。

<强> 1。您无法覆盖数组的equals() / hashcode()方法 - 这是一个问题,因为HashMap无法正确判断它是否已查找是否正确。

<强> 2。每次要创建密钥时,您仍然在创建新对象。数组是对象 - 每次创建新对象都不会节省任何内容。也可以使用原始的Key对象。

可能的解决方案

所以我会假设你每次都想避免创建一个新对象的原因是因为你要在那个get(key)上调用HashMap很多。如果是这种情况,为什么不创建一个保留在Key对象内部的可变ArrayMap实例。每次要键入两个String时,只需将它们设置在可变Key实例中,并使用该可变实例进行查找。每当您想要查找一对Key的值时,就不会创建新的Strings

答案 1 :(得分:2)

在这些行中

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

您使用String[]作为密钥。该对象没有自定义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

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

答案 2 :(得分:2)

  

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

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

有几个相关的观点:

  1. 对象创建并不昂贵,特别是如果对象是短暂的。
  2. 确保软件性能特征的唯一方法是通过分析。

答案 3 :(得分:1)

在java中,array1.equals(array2)仅在array1 == array2时,即它们与内存中的确切实例完全相同。这样就可以使Map将它们视为单独的键。你最好使用Key类来获取地图的密钥