Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define 2 constructors with 2 different type of HashMaps?

I have a class with 2 HashMap fields as follows-

HashMap<String, Integer> map1;
HashMap<String, String> map2;

Now, I want to only pass one of the maps in the constructor, that is either of type of map1 or of map2. However, I am not able to define 2 different constructors with HashMaps of different types. Is that a workaround for this?

like image 438
Poojan Avatar asked Sep 26 '13 15:09

Poojan


People also ask

How can I combine two HashMap objects containing the different types?

Assuming that both maps contain the same set of keys, and that you want to "combine" the values, the thing you would be looking for is a Pair class, see here for example. You simply iterate one of the maps; and retrieve values from both maps; and create a Pair; and push that in your result map.

Can we add different data types in HashMap?

Yep Sure.. please find the edited answer.. The example is only all about how to add,search, retrieve values in HashMap.

Can you have 2 constructors?

The technique of having two (or more) constructors in a class is known as constructor overloading. A class can have multiple constructors that differ in the number and/or type of their parameters. It's not, however, possible to have two constructors with the exact same parameters.

Can a class have multiple constructors with different names?

No. It is not possible. It might be helpful if you explain what it is you're trying to achieve that makes constructors with different names seem like a desirable solution. What is it you're trying to do with your code?


1 Answers

A few options:

1) One constructor that takes both maps and is safe when passed a null.

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

2) Setters for each map

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;
    }
}

3) A builder that allows you to differentiate between the maps and constructs the object properly (calling the setters)

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();
    }
}

4) Static factory (as pointed out by Evgeniy Dorofeev below)

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
}
like image 64
digitaljoel Avatar answered Oct 19 '22 05:10

digitaljoel