1

I'm going to make a method that return ArrayList of multiple Object, like this:

public ArrayList<Object> getData(Object similar) {

    //I suppose that I have 2 ArrayList that already contain data here
    ArrayList<Human> humans = new ArrayList<Human>();
    ArrayList<Animal> animals = new ArrayList<Animal>();

    if (similar.getClass().equals(Human.class)) {
        return humans;
    }

    if (similar.getClass().equals(Animal.class)) {
        return animals;
    }

    return null;
}

My idea is check type of Object param, if it's Human class then return ArrayList of Human. But I can't return like that because of incompatible type.
The problem is the return object is not specific.
How do I fix it? Thank you!

5 Answers 5

1

I'm not sure why you would, a factory pattern sounds like a better idea, but maybe something like...

public <T> ArrayList<T> getData(T similar) {
    if (similar.getClass().equals(Human.class)) {
        return (ArrayList<T>) new ArrayList<Human>();
    }

    if (similar.getClass().equals(Animal.class)) {
        return (ArrayList<T>) new ArrayList<Animal>();
    }

    return null;
}

And then you should be able to use something like

ArrayList<Human> humans = getData(new Human());
ArrayList<Animal> animals = getData(new Animal());

to call it

Depending on how strict you want to be, you could also use something like...

if (Human.class.isInstance(similar)) {

which would allow you to capture sub classes of Human

To me, however, this makes no sense. Your method should clearly define what it is willing to do. Perhaps, instead of trying to use a single method to return data for multiple classes, perhaps you should consider using a factory pattern, for example...

public abstract class AbstractFactory<T> {
    public abstract List<T> getData();
}

public class HumanFactory extends AbstractFactory<Human>{

    @Override
    public List<Human> getData() {
        return new ArrayList<>(); // Or what ever data you need it filled with
    }

}

public class AnimalFactory extends AbstractFactory<Animal>{

    @Override
    public List<Animal> getData() {
        return new ArrayList<>(); // Or what ever data you need it filled with
    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

ArrayList<Human> humans = getData(new Human()); is silly; if he knows he wants and ArrayList<Human>, he can just use ArrayList<Human> humans = new ArrayList<Human>()
@DarkSquirtings Duh, I just followed allowing with what the OP started with, as I said, I'd simply use a factory pattern if I was really that concerned
1

I'm not sure if this is what you are looking for but if I understand what you are trying to do correctly this should work.

You can simplify what you are doing by using generics

public ArrayList<T> getData(T similar) {
    return new ArrayList<T>();
}

This will return an ArrayList of whatever type you pass into the function.

1 Comment

How is this an improvement over just calling new ArrayList<MyClass>() to start with? He can't call the method without knowing the class either.
0

Here is where you use generic methods! You should change your code to this:

public <T> ArrayList<T> getData (T similar) {
    return new ArrayList<T> ();
}

But this really doesn't make sense. Because Why would you want a method to create an ArrayList? You can just create one of whatever type you like like this:

ArrayList<WhateverTypeYouLike> = new ArrayList<> ();

But if you really want to do this, here's some more info on generic methods:

https://docs.oracle.com/javase/tutorial/extra/generics/methods.html

4 Comments

I know how to create an ArrayList like that, but it's not what I'm asking for. My method get the type of param, depend on it, I know what should I return. I edited my question, I hope it's more clearly!
But why do you want this? If you can pass an object to a method, you must know it's type. That means you can just create an array list using the type of the object. There is no need to write a method. Is this a homework or something? @NgoKimHuynh
I know that I can make 2 methods that return ArrayList<Human> and ArrayList<Animal>. But if my idea is possible, I don't need to write 2 times.
It seems like that you misunderstood me. But whatever.
0

Here's the problem: if your method definition says that you're returning an ArrayList<Object>, then the caller expects to receive an ArrayList<Object>. An ArrayList<Human> is more restricted in what can be placed in it, and as such fails to fulfill the contract set forward in the class definition.

Furthermore, if you don't know what class the object you're passing into the method to create the ArrayList is at compile time, then you won't know what kind of ArrayList you're receiving either, so even if your method did work it wouldn't do you any good.

I'm not sure what you're trying to do, but the first step is probably to make sure that you're not just trying to engineer a more complicated way to use ArrayList<Human> myList = new ArrayList<Human>();

Comments

0

You're code does not compile, because ArrayList<Human> is not a subtype of ArrayList<Object>. With arrays, that is different. Human[] is a subtype of Object[]. The reason for that is preventing runtime errors by using the type system. If you'r code would compile a caller might do the following:

ArrayList<Object> aList = getData(new Human());
list.add("some String");

After all, aList is supposed to contain arbitrary Objects, therefore this compiles. If you do that with arrays. You get an ArrayStoreException when adding the String.

What can be done about this? That depends on your requirements. But probably the code presented by @Sweeeper and @FrozenHawk should work for you:

public <T> ArrayList<T> getData (T similar) {
  return new ArrayList<T> ();
}

If this is not your intention, please ask in the comments. There are more patterns for that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.