Most efficient way to cast ListSubClass to ListBaseClass
The syntax for this sort of assignment uses a wildcard:
List<SubClass> subs = ...;
List<? extends BaseClass> bases = subs;
It's important to realize that a List<SubClass>
is not interchangeable with a List<BaseClass>
. Code that retains a reference to the List<SubClass>
will expect every item in the list to be a SubClass
. If another part of code referred to the list as a List<BaseClass>
, the compiler will not complain when a BaseClass
or AnotherSubClass
is inserted. But this will cause a ClassCastException
for the first piece of code, which assumes that everything in the list is a SubClass
.
Generic collections do not behave the same as arrays in Java. Arrays are covariant; that is, it is allowed to do this:
SubClass[] subs = ...;
BaseClass[] bases = subs;
This is allowed, because the array "knows" the type of its elements. If someone attempts to store something that isn't an instance of SubClass
in the array (via the bases
reference), a runtime exception will be thrown.
Generic collections do not "know" their component type; this information is "erased" at compile time. Therefore, they can't raise a runtime exception when an invalid store occurs. Instead, a ClassCastException
will be raised at some far distant, hard-to-associate point in code when a value is read from the collection. If you heed compiler warnings about type safety, you will avoid these type errors at runtime.
Cast the sub class List to base class List
No it will not work directly except you define your first list as:
List<? extends Animals> animal;
then you will be able to do:
List<Puppy> puppy = new ArrayList<Puppy>();
animal = puppy;
Convert ListDerivedClass to ListBaseClass
The way to make this work is to iterate over the list and cast the elements. This can be done using ConvertAll:
List<A> listOfA = new List<C>().ConvertAll(x => (A)x);
You could also use Linq:
List<A> listOfA = new List<C>().Cast<A>().ToList();
Convert List of Base Class to a List of Derived Class - possible?
Cast<T>
method applies cast operation to all elements of the input sequence. It works only if you can do the following to each element of the sequence without causing an exception:
ParentClass p = ...
ChildClass c = (ChildClass)p;
This will not work unless p
is assigned an instance of ChildClass
or one of its subclasses. It appears that in your case the data returned from the server API contains objects of ParentClass
or one of its subclasses other than ChildClass
.
You can fix this problem by constructing ChildClass
instances, assuming that you have enough information from the server:
List<ChildClass> childList = parentList
.Select(parent => new ChildClass(parent.Name, ... /* the remaining fields */))
.ToList();
Casting a list of an object to a list of super types
Java Generics are invariant. This means that, given two concrete classes, A
and B
, SomeClass<A>
has no relationship to SomeClass<B>
, even if B
is a subtype of A
.
So, List<RangeData>
is not a supertype of List<IncomeRanges>
. Instead, you should use an upper bounded wildcard, like this:
public RangeData findRangeData(List<? extends RangeData> list, int value) {
....code....
}
For more information, you can check the documentation on Generics, Inheritance, and Subtypes.
How do you cast a List of supertypes to a List of subtypes?
Simply casting to List<TestB>
almost works; but it doesn't work because you can't cast a generic type of one parameter to another. However, you can cast through an intermediate wildcard type and it will be allowed (since you can cast to and from wildcard types, just with an unchecked warning):
List<TestB> variable = (List<TestB>)(List<?>) collectionOfListA;
Copying a ListBaseClass to ListDerivedClass
List<DerivedClass> result =
listBaseClass.ConvertAll(instance => (DerivedClass)instance);
Actually ConvertAll is good when you need to create new objects based on the original, when you just need to cast you can use the following
List<DerivedClass> result =
listBaseClass.Cast<DerivedClass>().ToList();
If not all of the items in your list can be cast to DerivedClass then use OfType instead
List<DerivedClass> result =
listBaseClass.OfType<DerivedClass>().ToList();
Converting a collection of subtype to collection of supertype
Easiest way, assuming you don't need to modify the collection through as1
:
Collection<A> as1 = Collections.unmodifiableCollection(bs);
If you do need to modify the collection, the only safe thing to do is to copy it:
Collection<A> as1 = new ArrayList<>(bs);
Insert a BaseClass instance into a List? extends BaseClass (Java)
Java keyword extends in generic type of reference is used to restrict actual generic type realization to be no less derived than the named type. Especially it can be a subclass. One should use it in case type is used to extract values and operate on them. You then use the interface of the base class not concerning the actual type (realization/implementation) of that class.
When you've got a specific class and need to pass (put) into collection, or other generic class object, the reference to point at that object should have super keyword, which restricts the actual object to be no more derived than the named type.
Code example below. Assume we have classes Base
and Derived
, where Derived extends Base
, class Base
have an interface method foo()
and both have default constructor.
void service() {
List<Base> theList = new ArrayList<Base>();
produceObjects(theList);
consumeObjects(theList);
}
void produceObjects(List<? super Base> consumerList) {
consumerList.add(new Derived());
}
void consumeObjects(List<? extends Base> producerList) {
for (Base base : producerList) {
base.foo();
}
}
Related Topics
Networksecurityconfig: No Network Security Config Specified -- Android 7.0 Error
R.Raw.Anything Cannot Be Resolved
How to Iterate Through the Id Properties of R.Java Class
How to Implement the Android Actionbar Back Button
How to Create JSON Object Using String
Transparent Blurry View Which Blurs Layout Underneath
Android - Get Value from Hashmap
Add Object to Arraylist at Specified Index
Fatal Exception: Firebase-Messaging-Intent-Handle -- Java.Lang.Noclassdeffounderror
How to Fix Install_Parse_Failed_Manifest_Malformed in My Android Application
Theme.Appcompat.Light.Darkactionbar - No Resource Found
What Would an Ast (Abstract Syntax Tree) for an Object-Oriented Programming Language Look Like
No Resource Identifier Found for Attribute 'Layout_Behavior' in Package
How to Pass an Arraylist to a Varargs Method Parameter
How to Get Selected Xls File Path from Uri for Sdk 17 or Below for Android