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?

jww
  • 97,681
  • 90
  • 411
  • 885
sammy333
  • 1,384
  • 6
  • 21
  • 39
  • 1
    Collection> (http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html) – CodeFanatic Aug 17 '14 at 19:34
  • Could you please clarify? I do not understand what you want to achieve. – Gábor Bakos Aug 17 '14 at 19:35
  • If you dont what type is it then youll get yourself in trouble when getting the objects out from the list – Rod_Algonquin Aug 17 '14 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. – Hot Licks Aug 17 '14 at 19:51

3 Answers3

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Of course, folks managed using Java quite well for about 10 years without generics, where every collection object was a collection of `Object`. – Hot Licks Aug 17 '14 at 19:48
  • 1
    And dynamically typed languages like Groovy resolutly prefer that you leave the generics out (though you can write them [for the sake of documentation](http://groovy.codehaus.org/Generics)) – David Tonhofer Aug 17 '14 at 20:05
  • 3
    @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`. – Jon Skeet Aug 17 '14 at 20:29
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); }
    }
}
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
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());
    }

}
David Tonhofer
  • 14,559
  • 5
  • 55
  • 51