-1

The task specification is as follows: "Your task is to create Multiplicator that receives Folders with anything that can be copied (i.e. implementing Copy interface) and creates an array of Folders with copies of the original Folder content."

I am trying to figure out how to add objects into the array. However, when I run the code that I have written, I get an output of null.

How can I add generic objects into an array?

import java.util.ArrayList;
import java.util.List;

/**
 * Class to work with
 */
class Multiplicator {
    public static <T extends Copy<T>> Folder<T>[] multiply(Folder<T> folder, int arraySize) {
        // Method to implement
        Folder myFolder = new Folder();
        Folder<T>[] folderArray = new Folder[arraySize];
        for (int i = 0; i < arraySize; i++) {
            folderArray[i] = (Folder<T>) myFolder.get();
        }
        return folderArray;
    }

    public static void main(String[] args) {
        System.out.println("Well done!");
    }

}

// Don't change the code below
interface Copy<T> {
    T copy();
}

class Folder<T> {

    private T item;

    public void put(T item) {
        this.item = item;
    }

    public T get() {
        return this.item;
    }
}

1 Answers1

1

The problem is not how you created a new array of a generic type. In fact, you created a Folder<T>[] correctly, using new Folder[arraySize]. Yes, there is a warning, but that is because of a restriction/flaw in Java's type system.

The reason why it's all null, is because you created an empty folder, Folder myFolder = new Folder();, and put its contents (null) into the array (folderArray[i] = (Folder<T>) myFolder.get();).

According to the task description, you should be copying the contents of the folder provided as one of the parameters, folder:

public static <T extends Copy<T>> Folder<T>[] multiply(Folder<T> folder, int arraySize) {

    Folder<T>[] folderArray = new Folder[arraySize];

    // for arraySize times...
    for (int i = 0; i < arraySize; i++) {
        // create a new, empty folder
        Folder<T> newFolder = new Folder<>();
        // put the copy of the parameter folder's contents into the new folder
        newFolder.put(folder.get().copy());
        // put the new folder into the array
        folderArray[i] = newFolder;
    }
    return folderArray;
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Thank you. I am new to generics and can see now that I should create an instance of Folder and not an object of Folder. Just to confirm, when I instantiate Folder, I am able to access the methods in classes and interfaces associated with T? – Riko Kurahashi Jun 18 '20 at 10:09
  • @RikoKurahashi What do you mean by "associated with `T`"? You are able to access `copy` here because in the method signature, it is said that `T extends Copy`. – Sweeper Jun 18 '20 at 10:11
  • My apologies, I was looking at Folder copy and how it links to T extends Copy. With Folder copy = new Folder<>();, this allows the Copy interface to work as T is being utilized? Edit: I will try to search for documentation about the differences between creating objects and Folder as I think that is where my confusion lays. – Riko Kurahashi Jun 18 '20 at 10:16
  • @RikoKurahashi I've realised I might have used some confusing names here. I've edited my answer. Essentially, `folder.get()` returns a `T` because `folder` is a `Folder` (look at the parameter!). Now, why can you use `.copy()` on `folder.get()`? Because `T` is also a `Copy` according to the constraint in the method signature. – Sweeper Jun 18 '20 at 10:21
  • @RikoKurahashi For the difference between `Folder` and `Folder`: https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it – Sweeper Jun 18 '20 at 10:22
  • Thank you. I understand why we need for instantiation as it links to the other methods. – Riko Kurahashi Jun 18 '20 at 10:29
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/216200/discussion-between-sweeper-and-riko-kurahashi). – Sweeper Jun 18 '20 at 10:30