如何使用2种不同类型的HashMaps定义2个构造函数?

Poo*_*jan 16 java polymorphism constructor hashmap

我有一个包含2个HashMap字段的类如下 -

HashMap<String, Integer> map1;
HashMap<String, String> map2;
Run Code Online (Sandbox Code Playgroud)

现在,我想只传递构造函数中的一个映射,即map1或map2的类型.但是,我无法使用不同类型的HashMap定义2个不同的构造函数.这是一个解决方法吗?

dig*_*oel 26

一些选择:

1)一个构造函数,它接受两个映射,并在传递null时是安全的.

public MyClass( Map<String, Integer> map1, Map<String, String> map2 ) {
    if ( map1 != null ) { this.map1 = map1; }
    if ( map2 != null ) { this.map2 = map2; }
}
Run Code Online (Sandbox Code Playgroud)

2)每个地图的设定者

public MyClass {
    private Map<String, Integer> map1;
    private Map<String, String> map2;
    public void setMap1( Map<String, Integer> map1 ) {
        this.map1 = map1;
    }
    public void setMap2( Map<String, String> map2 ) {
        this.map2 = map2;
    }
}
Run Code Online (Sandbox Code Playgroud)

3)一个构建器,允许您区分地图并正确构造对象(调用setter)

public MyClass {
    private Map<String, Integer> map1;
    private Map<String, String>  map2;
    // pretend you don't want people to be able to swap out the map after construction so you protect the setter here.
    protected void setMap1( Map<String, Integer> map1 ) {
        this.map1 = map1;
    }
    protected void setMap1( Map<String, String> map2 ) {
        this.map2 = map2;
    }
    // getters for the maps and other properties
    public static Builder builder() {
        return new Builder();
    }
    public static class Builder {
        private Map<String, Integer> map1;
        private Map<String, String> map2;
        public Builder withMap1( Map<String, Integer> map ) {
            map1 = map;
            return this;
        }
        public Builder withMap2( Map<String, String> map ) {
            map2 = map;
            return this;
        }
        public MyClass build() {
            MyClass c = new MyClass();
            // possibly conditional code that inspects the maps for specific values or validity
            c.setMap1( map1 );
            c.setMap2( map2 );
            // initialization of other fields
            return c;
        }
    }

    public static void main( String[] args ) {
        // sample usage
        MyClass instance1 = MyClass.builder().withMap1(myMap1).build();
        MyClass instance2 = MyClass.builder().withMap2(myMap2).build();
        MyClass instance3 = MyClass.builder().withMap1(myMap1).withMap2(myMap2).build();
    }
}
Run Code Online (Sandbox Code Playgroud)

4)静态工厂(由下面的Evgeniy Dorofeev指出)

public MyClass {
    private Map<String, Integer> map1;
    private Map<String, String> map2;
    // other properties

    private MyClass() {}

    public static MyClass withMap1(Map<String, Integer> map ) {
        MyClass c = new MyClass();
        c.map1 = map;
        return c;
    }
    public static MyClass withMap2(Map<String, String> map ) {
        MyClass c = new MyClass();
        c.map2 = map;
        return c;
    }
    // getters and setters
}
Run Code Online (Sandbox Code Playgroud)


Bat*_*eba 13

你不能:在编译阶段,泛型被剥离:编译后的代码只能HashMap<Object, Object>在两种情况下看到.

此过程的技术名称是类型擦除.请参见http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

在很多方面,Java泛型都不如C++模板.


Evg*_*eev 8

作为一种解决方法,您可以使用具有不同名称的静态工厂方法