1

Say I have 2 arrays of objects which all extend the same abstract class, and I want the second list's first element to be a new instance of the same class which the first element in the first array is (this assumes that they take the same parameters).

Animals[] animals1 = new Animals[] {new Cat(), new Dog()...}

Animals[] animals2 = new Animals[] {new animals1[0].getClass()} //doesn't work obviously

Is there a way of doing this?

Andreas Sandberg
  • 241
  • 1
  • 3
  • 10

2 Answers2

1

You could do something like this:

Animal.java

public interface Animal {
}

Cat.java:

public class Cat implements Animal {
}

Dog.java:

public class Dog implements Animal {
}

Code to do the mapping:

Animal[] animals1 = new Animal[] {new Cat(), new Dog()};
Animal[] animals2 = Arrays.stream(animals1).map(a -> {
    Animal animal = null;
    try {
        animal = a.getClass().getDeclaredConstructor().newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return animal;
}).toArray(Animal[]::new);
Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
0

I would create an abstract method newInstance() in the abstract base class, and make the subclasses create and return its own kind. For instance,

public abstract class Animal {
   // ... other methods
   public abstract Animal newInstance(/* parameters */);
}

public class Dog extends Animal {
    // ... other methods, fields
    @Override
    public Animal newInstance(/* parameters */) {
        Dog d = new Dog(/* ... */);
        // ...
        return d;
    }
}
// do this for other animals, they should instantiate and return their class

and for the list:

Animals[] animals2 = new Animals[] {animals[0].newInstance(/* ... */), ...};
Ege Hurturk
  • 693
  • 1
  • 10
  • 12