Java Java Data Structures Efficiency! Implement Chooser UI

Andre Kucharzyk
Andre Kucharzyk
4,479 Points

Why we can pass array to the list?

in this line of code:

 private String promptArtist() {
      System.out.println("Available artists: ");
      List<String> artists = new ArrayList<>(songBook.getArtist()); <-------------
    }

we are passing Set into a List? Why is it possible?

2 Answers

Brendon Butler
Brendon Butler
4,235 Points

Passing a collection into another collection allows it to be converted and inherit the properties of the new collection while retaining its original values. Some collections may lose information, such as if you were to pass a list into a set. If you had duplicate elements in that list, they would omit these causing you to lose some data.

A Set is a type of Collection that does not allow duplicate elements.

A List, however, is a type of Collection that does allow duplicate elements.

set.add("Pie");
set.add("Cake");
set.add("Pie");

list.add("Pie");
list.add("Cake");
list.add("Pie");

// VALUES IN SET (index:value) 0:"Pie", 1:"Cake"
// VALUES IN LIST (index:value) 0:"Pie", 1:"Cake", 2:"Pie"
Andre Kucharzyk
Andre Kucharzyk
4,479 Points

Hey Brendon, thanks for the answer, but my question was not what we can do, but WHY we can do it? Where is code is that determined that, for example, List allows Set as a parameter?

Brendon Butler
Brendon Butler
4,235 Points

I'm not sure how much Java knowledge you have, but it is kinda hard to explain (at least for me). The best way I can describe it is by making my own classes.

Public class Example {
    public static void main(String[] args) {
        List<Item> items = new ArrayList<>(/* create/initialize list (add items to list) */);

        // this will create a box with the items listed above
        Box box = new Box(items);

        // this will create a cabinet with items from the box (as long as they are a Plate) see Cabinet class
        Cabinet cabinet = new Cabinet(box);
    }
}

/*
* This is an interface, it's essentially a blueprint for Java classes.
*
* Any methods in this interface have to be implemented by any classes that use these "blueprints."
*/
Public interface Container {
    public List getItems();
}

Public class Box implements Container {
    private List<Item> items;

    // contructor
    Box (Container container) {
        items = container.getItems();
        // It may be this simple, or there may be conversions involved in the constructor (see Cabinet)
    }

    public List getItems() {
        return items;
    }
}

Public class Cabinet implements Container {
    private List<Item> items;

    // cabinet contructor (only adds Plates to the list)
    Cabinet (Container container) {
        for (Item item : container.getItems()) {
            if (item.getType().equals(ItemType.PLATE))
                items.add(item);
        }
    }

    public List getItems() {
        return items;
    }
}

Interface classes can be tricky when first learning, but basically since both the Box and Cabinet class are both types of Containers. They share all the same methods that the Containers class predefined. So you could pass either a Box or a Cabinet into the Box class since the contructor is looking for a type of container.

If you were to pass a container into the Box class it will take all the items from the class being passed in and initialize the items list using those items. Kind of like passing a Set into a List.

If you were to pass a container into the Cabinet class it will only take the items that are of the Plate type and initialize the items list using those items. Kind of like how a Set would filter out any duplicates from a List (see my other answer). And only add unique values.

Please note: This is just a basic understanding and I wrote it very quickly. All the code is pseudo-code so it will probably not compile correctly if you test it without modification.

Brendon Butler
Brendon Butler
4,235 Points

To answer your question more directly, you basically have to look at a classes Contructor and what kind of classes can be passed in. If you look at the class(es) it accepts and it happens to be an interface, try to find out what classes use this interface (you can do this by looking up the Java SE JDK documentation, I added a link to this in my other answer).

Source Java classes will be more difficult to decipher. But this should give you a basic understanding until you become more advanced.