开发者

Collection in Java

Quick Question... Can collections in Java hold more than one type? Or do they all have to be the same type?

thanks开发者_StackOverflow社区


Simple answer

Yes.

More detailed answer

You can either use generic collection, without <T> value, for example:

ArrayList a = new ArrayList();
a.add(2);
a.add("String");

Using collections without <T> is a bad habit and most IDEs / compilers give a warning here. You can circumvent it by using a collection of Object, i.e.:

ArrayList<Object> a = new ArrayList<Object>();

Or you can find some common interface or supertype that these element must have in, for example ArrayList<Number> - and you can store various objects that have common Number superclass, i.e. BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short:

ArrayList<Number> a = new ArrayList<Number>();
a.add(2); // integer
a.add(42L); // long
a.add(123.45d); // double
System.out.println(a.toString()); // => [2, 42, 123.45]

Note that it essentially means that a elements are of Number class — i.e. you can't ask to execute subclass-specific methods (for example, Double#isInfinite(), which doesn't exist in Number superclass), although you can typecast in run-time if you somehow know it's safe to typecast:

a.get(2).isInfinite()          // compile-time error
((Double) a.get(2)).isInfinite() // => false
((Double) a.get(1)).isInfinite() // run-time error (ClassCastException)

Run-time typecasting is also generally frowned upon, as it effectively circumvents proper compile-time type safety.

Also note that it's impossible to assign (or use) ArrayList<Number> in place of ArrayList<Integer> and vice-versa, i.e. this will fail to compile:

public void printNumbers(ArrayList<Number> list) {
    list.forEach(System.out::println);
}
ArrayList<Integer> a = new ArrayList<Integer>();
printNumbers(a); // "incompatible types"

as well as this:

public void printIntegers(ArrayList<Integer> list) {
    list.forEach(System.out::println);
}
ArrayList<Number> a = new ArrayList<Number>();
printIntegers(a); // "incompatible types"

To declare a variable to be able to accept both ArrayList<Number> or any of its subclasses, one can use ArrayList<? extends Number> or ArrayList<? super Number> syntax. extends is generally used when you're going to consume (i.e. read) from the object in your method, super is used when you're going to produce (i.e. write). Given that printout is consuming, it's safe to use extends:

public void printNumbers(ArrayList<? extends Number> list) {
    list.forEach(System.out::println);
}

ArrayList<Integer> listInt = new ArrayList<Integer>();
printNumbers(listInt); // works
ArrayList<Double> listDbl = new ArrayList<Double>();
printNumbers(listDbl); // also works

There is a good answer in Difference between <? super T> and <? extends T> in Java for more in-depth explanation.


If you want them to hold any more than one type, use Collection<Object>. However, you won't know what you're getting without doing some if (x instanceof MyType) calls, which are rather inefficient.


They have to be of the same Supertype. So if you have objects of type A, then a Collection<A> can store objects of type A and of every subtype of A.

If you want to allow arbitrary types, then use Collection<Object>, otherwise take the most general appropriate super-class.

However, you will then have to manually cast from the most general type (Object) to the specific type you have in mind. You can use the typeof operator to find out what the type is.


Every Collection classes can contains heterogeneous objects except TreeSet and TreeMap. Since TreeSet and TreeMap stores elements according to some sorting order. so, if objects are of different type it will not be able to sort it because comparison between the objects will not be possible for sorting.


Yes they can but they should not (that's why generics have been put in place since 5th version of jdk) in general store different types, as this is the straight way to errors.


Yes collections in java can hold more than one type as below. But it will throw an exception if done using the following way.

    ArrayList al = new ArrayList();
    al.add(1);
    al.add("name");
    al.add(1.2f);

    Iterator itr =al.iterator();
    while(itr.hasNext())
    {
        System.out.println(itr.next());
    }

Hence it's better to mention the type that you're using. To get rid of the exception the above program can be modified as below.

    ArrayList<Integer> al = new ArrayList<Integer>();
    al.add(1);
    al.add(2);
    al.add(3);

    Iterator itr =al.iterator();
    while(itr.hasNext())
    {
        System.out.println(itr.next());
    }

    ArrayList<String> al1 = new ArrayList<String>();
    al1.add("Words");
    al1.add("Names");
    al1.add("Characters");

    Iterator itr1 =al1.iterator();
    while(itr1.hasNext())
    {
        System.out.println(itr1.next());
    }

You can also use more than these types.


Yes,

My mistake the correct code is this one and

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

or

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

should be the correct declaration if you want to use Generics in Collection.

class Test
{
   public static void main(String[] args)
   {
      // For Generic class of List
      ArrayList<E> arrL1 = new ArrayList<E>();
      arrL1.add("stackoverflow");
      arrL1.add(1);   
      Iterator itr1=list.iterator();

     while(itr1.hasNext())
     {
        System.out.println(itr1.next());
     }


  // for Particular datatype in List
    ArrayList<String> list=new ArrayList<String>(); // Creating arraylist
    list.add("Ravi"); // Adding object in arraylist
    list.add("Vijay");
    list.add("Ravi");
    list.add("Ajay");

    // transversing the values
    Iterator itr=list.iterator();
    while(itr.hasNext())
    {
        System.out.println(itr.next());
    }
}

}

Output 1

stackoverflow

1

Output 2

Ravi

Vijay

Ravi 

Ajay


I believe you can also use Collection<?>.


Yes, you can have more than one datatype in ArrayList of Collection.

class Test
{
    public static void main(String[] args)
    {
        // For Generic class of List
        ArrayList<> arrL1 = new ArrayList<>();
        arrL1.add("stackoverflow");
        arrL1.add(1);

        // for Particular datatype in List
        ArrayList<String> list=new ArrayList<String>(); // Creating arraylist
        list.add("Ravi"); // Adding object in arraylist
        list.add("Vijay");
        list.add("Ravi");
        list.add("Ajay");

        // transversing the values
        Iterator itr=list.iterator();
        while(itr.hasNext())
        {
            System.out.println(itr.next());
        }
    }
}

Output 1:

stackoverflow

1

Output 2:

Ravi

Vijay

Ravi

Ajay

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜