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
精彩评论