0

For example, can I create List that will contain String and other List? And if I can do that, what is the specific of my List? I can just say that it contains data of type Object, right?

4
  • 1
    Collection<?> (docs.oracle.com/javase/tutorial/extra/generics/wildcards.html) Commented Aug 17, 2014 at 19:34
  • Could you please clarify? I do not understand what you want to achieve. Commented Aug 17, 2014 at 19:35
  • If you dont what type is it then youll get yourself in trouble when getting the objects out from the list Commented Aug 17, 2014 at 19:37
  • Folks tell you it can't be done because they figure you're brain dead and can't somehow work out what kind of object you have when you get it out of the collection. It simply requires programming. Commented Aug 17, 2014 at 19:51

3 Answers 3

2

Yes, you can use:

List<Object> list = new ArrayList<>();
list.add("A string");
list.add(new ArrayList<Foo>());
// etc

It's usually not a good idea, as when you get items out of the list, it can be a pain to work out what you need to do with them. If you can design your way out of that, it would be a good idea... but the above will work.

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

3 Comments

Of course, folks managed using Java quite well for about 10 years without generics, where every collection object was a collection of Object.
And dynamically typed languages like Groovy resolutly prefer that you leave the generics out (though you can write them for the sake of documentation)
@HotLicks: Yes, but then in most cases you'd still have a logically single-type collection. Most of the time you'd just unconditionally cast after calling get.
0

Type-safe heterogeneous collections, without a language that supports sum types, gets pretty hairy. Here's an example of a list containing both String and int.

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

public class Foo {

    public static void main(String[] args) {

        // Construct the list by wrapping the elements in StringOrInt
        List<StringOrInt> list = new ArrayList<>();
        list.add(StringOrInt.apply("abc"));
        list.add(StringOrInt.apply(4));

        // Use the elements by applying a StringOrInt.Visitor.
        List<String> list2 = new ArrayList<>();
        for (StringOrInt x : list) {
            list2.add(x.apply(new StringOrInt.Visitor<String>() {
                public String caseString(String x) { return "String: " + x; }
                public String caseInt(int x) { return "Int: " + x; }
            }));
        }

        System.out.println(list2); // [String: abc, Int: 4]
    }
}

abstract class StringOrInt {

    interface Visitor<A> {
        A caseString(String x);
        A caseInt(int x);
    }

    private StringOrInt() {}

    abstract <A> A apply(Visitor<A> visitor);

    static StringOrInt apply(String x) { return new String_(x); }
    static StringOrInt apply(int x) { return new Int_(x); }

    private static final class String_ extends StringOrInt {
        final String x;
        String_(String x) { this.x = x; }
        <A> A apply(Visitor<A> visitor) { return visitor.caseString(x); }
    }
    private static final class Int_ extends StringOrInt {
        final int x;
        Int_(int x) { this.x = x; }
        <A> A apply(Visitor<A> visitor) { return visitor.caseInt(x); }
    }
}

1 Comment

Pretty nice, but I doubt this is worth the trouble.
0

Enjoy a test case

import java.util.LinkedList;
import java.util.List;

import org.junit.Test;

import static org.junit.Assert.*;

public class TestGenerics {

    @Test
    public void listOfObjects() {
        List<Object> objList = new LinkedList<Object>();
        objList.add("alphabeta");
        objList.add(Integer.valueOf(888));
        assertEquals("alphabeta",(String)(objList.get(0))); 
        assertEquals(888, ((Integer)(objList.get(1))).intValue());
    }

    @Test
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void listOfElementsThatAreSubclassedFromObject() {
        List<? extends Object> objList = new LinkedList();        
        // objList.add("alphabeta"); // WILL NOT COMPILE
        objList.add(null); // Only null can be added to this list
    }

    @Test
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void listOfElementsThatHaveSupertypeObject() {
        List<? super Object> objList = new LinkedList();
        objList.add("alphabeta");
        objList.add(Integer.valueOf(888));
        assertEquals("alphabeta",(String)(objList.get(0))); 
        assertEquals(888, ((Integer)(objList.get(1))).intValue());
    }

    @Test
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void rawListIsAlsoNice() {       
        List objList = new LinkedList();
        objList.add("alphabeta");
        objList.add(Integer.valueOf(888));
        assertEquals("alphabeta",(String)(objList.get(0))); 
        assertEquals(888, ((Integer)(objList.get(1))).intValue());
    }

}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.