Map 的 Java 泛型问题

标签 java generics

我有这个不应该编译。

public boolean foo(final Map<String, String> map) {
     map.get(1);   // No error here?
}

最佳答案

get 方法接受一个 Object,因此 1 被自动装箱为一个 Integer 并且它编译得很好。不过,您总是会返回 null 作为响应。

这样做是为了向后兼容。

// Ideal Map:
public V get(K key) {
 // impl here
}

// what we have
public V get(Object key) {
 // impl here
}

天蝎座的例子

import java.util.*;
class ScorpMain {

    /* This interface just has a single method on it returning an int */
    static interface SomeInterface {
        int foo();
    }

    /**
     * ExampleKey has an int and a string. It considers itself to be equal to
     * another object if that object implements SomeInterface and the two have
     * equal foo values. It believes this is sufficient, as its sole purpose is
     * to calculate this foo value.
     */
    static class ExampleKey implements SomeInterface {
        int i;
        String s;
        ExampleKey(int i, String s) { this.i = i; this.s = s; }
        public int foo() { return i * s.length(); }
        public int hashCode() { return i ^ s.hashCode(); }
        // notice - equals takes Object, not ExampleKey
        public boolean equals(Object o) {
            if(o instanceof SomeInterface) {
                SomeInterface so = (SomeInterface)o;
                System.out.println(so.foo() + " " + foo());
                return so.foo() == foo();
            }
            return false;
        }
    }

    /**
     * The ImposterKey stores it's foo and hash value. It has no calculation 
     * involved. Note that its only relation to ExampleKey is that they happen
     * to have SomeInterface.
     */
    static class ImposterKey implements SomeInterface {
        int foo;
        int hash;
        ImposterKey(int foo, int hash) { this.foo = foo; this.hash = hash; }
        public int foo() { return foo; }
        public boolean equals(Object o) {
                SomeInterface so = (SomeInterface)o;
                return so.foo() == foo();
        }
        public int hashCode() { return hash; }
    }

    /**
     * In our main method, we make a map. We put a key into the map. We get the
     * data from the map to prove we can get it out. Then we make an imposter, 
     * and get the data based on that. 
     * The moral of the story is, Map.get isn't sacred: if you can trick it 
     * into thinking that the object inside is equal to the object you give it 
     * in both equality and hash, it will give you the resulting object. It 
     * doesn't have anything to do with the type except that a given type is 
     * unlikely to be equal to another object that isn't of the given type.
     * This may seem like a contrived example, and it is, but it is something 
     * to be conscious of when dealing with maps. It's entirely possible you 
     * could get the same data and not realize what you're trying to do. Note 
     * you cannot ADD the imposter, because that IS checked at compile time.
     */
    public static void main(String[] args) {
        Map<ExampleKey,String> map = new HashMap<ExampleKey,String>();
        ExampleKey key = new ExampleKey(1337,"Hi");
        map.put(key,"Awesome!");
        String get = map.get(key);
        System.out.println(get); // we got awesome
        ImposterKey imposter = new ImposterKey(2674,3096); // make an imposter
        String fake = map.get(imposter);
        System.out.println(fake); // we got awesome again!
    }
}

关于Map 的 Java 泛型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7532435/

相关文章:

java - 覆盖 Java 泛型方法

用于 PDF 页面拆分的 Java 库

java - 生成一个 Java 可用的正则表达式,在精确位置否定单词

Java:编写 SQL 语句

c# - 对于 C#,是否可以在泛型类的实例声明中指定类型约束?

使用双泛型的 C# 类 : give only one when both of them should be the same?

java - 无法启动组件 [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/LabWebServletHibernate]]

java - SurefireReflectionException

java - 为什么在填充包含 < 类型元素的集合时行为会有所不同?扩展 T>?

Java:通用静态多维数组