Using Map Arguments in the Constructor

I have a class Student

with this constructor.

 public Student(String name, int age, Map<String, Integer> grades) {
    this.setName(name);
    this.setAge(age);
    this.setGrades(grades);
 }

      

when creating a Student object, how do I pass the Map argument in the constructor?

Something looks like something similar:

List<Student> roster = new ArrayList<>();
roster.add(new Student("Ann Droid", 145, Arrays.asList(96, 78)));

      

If I had this constructor:

public Student(String name, int age, List<Integer> grades) {
    this.setName(name);
    this.setAge(age);
    this.setGrades(grades);
 }

      

+3


source to share


5 answers


Vanilla flavor plain Java has nothing for Maps like Arrays.asList()

. Therefore, you will have to initialize Map

over several lines of code like this:

Map<String, Integer> grades = new HashMap<String, Integer>();
grades.put("English", 90);
roster.add(new Student("Ann Droid", 145, grades);

      



However, with Google Guava, you can do this:

Map<String, Integer> grades = ImmutableMap.of("English", 90);

      

+4


source


This cannot be done with a single liner.



Map<String,Integer> grades = new HashMap<>();
grades.put("Math", 100);
roster.add(new Student("Ann Droid", 145, grades));

      

+3


source


Can't build Map

in the same slot with Java <= 7 and standard JDK. (Well, you can technically with a double-bound initializer, but that is considered bad practice).

In Java 8, you can use the Stream API for this:

import java.util.AbstractMap.SimpleEntry;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toMap;

...
new Student("Name", 
            10,
            Stream.of(new SimpleEntry<>("MyString", 1), 
                      new SimpleEntry<>("AnotherString", 2))
                  .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue)));

      

You should now see this if it improves readability or not for your use case;)

Or, you can change your design to Map<String, Integer>

be represented instead of List<Grade>

each Grade

having String

one representing the course and Integer

for the Student label for that course.

And then you can use Arrays.asList

:

new Student("John", 
            18, 
            Arrays.asList(new Grade("French", 1), new Grade("Math", 5)));

      

Of course, you must ensure that the ratings are unique.

+3


source


You can execute the utility function yourself. It's not very safe, however, because you have to bypass the typing to (ab) use the varags parameter.

public class MapExample
{
    public static <K, V> Map<K, V> map(Object... objects)
    {
        Map<K, V> map = new HashMap<>();
        for (int n = 0; n < objects.length; n += 2)
        {
            map.put((K)objects[n], (V)objects[n + 1]);
        }
        return map;
    }

    public static void main(String[] args)
    {
        System.out.println(map("AAA", 123, "BBB", 456));
    }
}

      

+3


source


You can try this option using the anonymous constructor

List<Student> roster = new ArrayList<Student>();
roster.add(new Student("Ann Droid", 145, new HashMap<String, Integer>(){{
                                         put("English", 78);
                                         put("Math", 96);
                                         }}));

      

Or you can use Guava's ImmutableMap of () , but this API is limited to five pairs.

List<Student> roster = new ArrayList<>();
roster.add(new Student("Ann Droid", 145, ImmutableMap.of("English", 78, "Math", 96);

      

+1


source







All Articles