滚动我自己的对象来替换Map <int [],String>&Map <ArrayList <String>,String>

sma*_*ish 0 java object

我正在尝试使用以下数据结构:

//all the words in each file as index, the label as value
static Map< ArrayList<String> , String > train__list_of_file_words = new HashMap<>();
static Map< ArrayList<String> , String > test__list_of_file_words = new HashMap<>();

//frequency count against global dictionary
static Map< int[] , String > train_freq_count_against_globo_dict = new HashMap<>();
static Map< int[] , String > test_freq_count_against_globo_dict = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

但我被告知这是非感性的,因为它们不能与equals()一起顺利工作并且是可变的.

我想解决方案是编写我自己的对象以类似的方式存储这些信息,但我以前从未这样做过.怎么做?

aio*_*obe 5

既然没有人挺身而出,对你的问题给出了完整的答案,我会试一试:

运用 Map< ArrayList<String> , String >

这种方法的问题ArrayList<String>是可变的.例如,请参见此示例:

Map<ArrayList<String>, String> map = new HashMap<>();

ArrayList<String> l = new ArrayList<>();
l.add("a");
l.add("b");

map.put(l, "Hello");
System.out.println(map.get(l)); // "Hello";

l.add("c"); // Mutate key.
System.out.println(map.get(l)); // null (value lost!)
Run Code Online (Sandbox Code Playgroud)

进一步阅读:

运用 Map< int[] , String >

这是可能的,但可能会令人困惑,因为两个阵列可能看起来相同,但.equals彼此不相同.请考虑以下示例:

Map<int[], String> map = new HashMap<>();

int[] arr1 = { 1, 2 };
map.put(arr1, "Hello");

int[] arr2 = { 1, 2 };
System.out.println(map.get(arr2));  // null, since arr1.equals(arr2) == false
Run Code Online (Sandbox Code Playgroud)

因此,要检索以前插入的值,您需要使用相同的实例作为键.以上示例仅在您使用时有效map.get(arr1).

那么该怎么办?

  • 您可以按照建议滚动自己的数据结构,以跟踪私有数据结构中的映射.例如,您可以使用a Map<List<...>, String>作为支持结构,但要确保您永远不会改变您在该映射中使用的键(例如,通过保持映射为私有而永远不会发布对List-keys的引用).

  • 如果您事先知道密钥的大小,则可以使用嵌套映射,如下所示:Map<String, Map<String, String>>.

  • 您可以使用第三方集合库,例如Guava或Apache Commons.他们有一个名为Tableresp 的数据结构.MultiKeyMap这两者似乎都符合您的要求.

  • 您可以按照@dasblinkenlight的建议创建一个新的,不可变的密钥对象.(提醒一句;这是安全的,因为它String是不可变的!)代码可以略微简化如下:

    final class StringTuple {
        private String[] vals;
    
        public StringTuple(String... vals) {
            this.vals = vals.clone();
        }
    
        public int hashCode() {
            return Arrays.hashCode(vals);
        }
    
        public boolean equals(Object obj) {
            return (obj instanceof StringTuple)
                && Arrays.equals(vals, ((StringTuple) obj).vals);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)