when to use Unbounded Wild Card in Java - java

I came to know the Unbounded Wild card but I didn't understand usage of it in realworld.
In Below program using and with out using this Unbounded Wildcard will be same at compile time.Then why we need Unbounded wild cards ?Please help to understand.
public class UnboundedWildCards {
public static void main(String args[])
{
List<Integer> intLst = new ArrayList<Integer>();
intLst.add(1);
intLst.add(11);
List<Double> doubleLst = new ArrayList<Double>();
doubleLst.add(1.1);
doubleLst.add(11.11);
List lst = new ArrayList();
lst.add(new Object());
lst.add(new Double(2.3));
lst.add(new Integer(2));
print(intLst);
print(doubleLst);
print(lst);
unBoundprint(intLst);
unBoundprint(doubleLst);
unBoundprint(lst);
}
public static void print(List lst)
{
for(Object o : lst)
System.out.println(o);
}
public static void unBoundprint(List<?> lst)
{
for(Object o : lst)
System.out.println(o);
}
}

Are you asking why do we need the notation
List<?>
when the simpler
List
is equivalent?
Using the wildcard is more explicit but the simpler syntax is required for backwards compatibility with pre-generics code. So you can use either interchangeably but there is also a third way of declaring this list which is also equivalent.
List<? extends Object> list;
This list will contain only objects of type Object. Since everything in Java extends from Object this is basically the same as saying unbounded.
Personally of the three I would probably use the first one because it is concise while still explicitly stating what the List should contain. If you just declared it as a List without a generic argument then it could be mistaken for a pre-generics list.
When would you ever want to use this? From experience I have only used this kind of unbounded list with legacy code. I was always taught to only put objects of one common type into a list (like a list of customers etc). However, people don't always write nice code and at times I've had to deal with lists containing different types. In these cases it was hard to move to a proper genericised list so I had to make do with an unbounded list.
It is possible that you may have a legitimate cause for an unbounded list. It depends what you want to do with those objects. If once they've been added to the list you only need to call methods from the Object class (like toString) or perhaps the List interface (like size), then perhaps you have a genuine use case for an unbounded list.

There are two scenarios where an unbounded wildcard is a useful approach:
If you are writing a method that can be implemented using functionality provided in the Object class.
When the code is using methods in the generic class that don't depend on the type parameter. For example, List.size or List.clear. In fact, Class is so often used because most of the methods in Class do not depend on T.
with examples
http://docs.oracle.com/javase/tutorial/java/generics/unboundedWildcards.html

At first it is important to understand that List<Object> and List<?> are not same. List<Object> is not super class of List<Anything that extends object> but List<?> or List<? extends Object> is super class of List<Anything that extends object>.
After keeping above point in mind go through printList example from this oracle's link https://docs.oracle.com/javase/tutorial/java/generics/unboundedWildcards.html

Related

List<?> list1 = new ArrayList<>(); Why I can't add this list1.add(1L); list1.add("hello"); to list1 (unbound wildcard)? [duplicate]

What does List<?> mean, does it mean simply a list of objects of unspecified type?
Googling for the string <?> returns nothing useful (:
As Tom said, the ?, or unbounded wildcard, means that the type of the object is not specified. It could be unknown, could be meant for multiple possible values or might be just plain irrelevant. Your example, List<?>, is pronounced "List of unknown." It's convenient because it's flexible, but there are also some pitfalls because you can't shove random objects in and pull them out of groups of unknown with total impunity.
Resources:
Wildcards are discussed here in the Java tutorial.
There's a good -- if verbose -- tutorial on generics in general by Angelika Langer available here.
And there's another good overview here (PDF) by Gilad Bracha; check out pages 5-7.
Finally, if you can get your hands on Effective Java by Josh Bloch, it's got a great section on generics and the cases in which you can, can't, should and shouldn't use wildcards (chapter 5, pages 109-146 in the second edition).
Incidentally, your Google search failed because Google doesn't truck with special characters:
With some exceptions, punctuation is ignored (that is, you can't search for ##$%^&*()=+[]\ and other special characters).
-Google help page
(EDIT: I must have been really tired when I wrote this last night. Cleaned up formatting/added a little info.)
The keyword you need to get more information is Wildcards
To answer this question I need to explain Unbounded Wildcards and Bounded Wildcards.
The content of this post has been assembled from java documentation.
1. Unbounded Wildcards
The unbounded wildcard type is specified using the wildcard character (?), for example, List<?>. This is called a list of unknown type. There are two scenarios where an unbounded wildcard is a useful approach:
If you are writing a method that can be implemented using functionality provided in the Object class.
When the code is using methods in the generic class that don't depend on the type parameter. For example, List.size or List.clear. In fact, Class<?> is so often used because most of the methods in Class<T> do not depend on T.
2. Bounded Wildcards
Consider a simple drawing application that can draw shapes such as rectangles and circles. To represent these shapes within the program, you could define a class hierarchy such as this:
public abstract class Shape {
public abstract void draw(Canvas c);
}
public class Circle extends Shape {
private int x, y, radius;
public void draw(Canvas c) {
...
}
}
public class Rectangle extends Shape {
private int x, y, width, height;
public void draw(Canvas c) {
...
}
}
These classes can be drawn on a canvas:
public class Canvas {
public void draw(Shape s) {
s.draw(this);
}
}
Any drawing will typically contain a number of shapes. Assuming that they are represented as a list, it would be convenient to have a method in Canvas that draws them all:
public void drawAll(List<Shape> shapes) {
for (Shape s: shapes) {
s.draw(this);
}
}
Now, the type rules say that drawAll() can only be called on lists of exactly Shape: it cannot, for instance, be called on a List<Circle>. That is unfortunate, since all the method does is read shapes from the list, so it could just as well be called on a List<Circle>. What we really want is for the method to accept a list of any kind of shape:
public void drawAll(List shapes) {
...
}
There is a small but very important difference here: we have replaced the type List<Shape> with List<? extends Shape>. Now drawAll() will accept lists of any subclass of Shape, so we can now call it on a List<Circle> if we want.
List<? extends Shape> is an example of a bounded wildcard. The ? stands for an unknown type, however, in this case, we know that this unknown type is in fact a subtype of Shape. (Note: It could be Shape itself, or some subclass; it need not literally extend Shape.) We say that Shape is the upper bound of the wildcard.
Similarly, the syntax ? super T, which is a bounded wildcard, denotes an unknown type that is a supertype of T.
A ArrayedHeap280<? super Integer>, for example, includes ArrayedHeap280<Integer>, ArrayedHeap280<Number>, and ArrayedHeap280<Object>.
As you can see in the java documentation for Integer class, Integer is a subclass of Number that in turn is a subclass of Object.
List: There is no type restriction and assignment restriction at all.
List<Object>: It seems to be used the same as List, but a compilation error will occur when accepting other generic assignments.
List<?>: It is a generic type. Before assignment, it means that it can accept any type of set assignment, but after assignment, you can't add elements to it, but you can remove and clear, not an immutable set. List<?> is generally used as a parameter to receive an external collection, or return a collection of specific element types, also known as a wildcard collection.
The test code and result as followed:
List a1 = new ArrayList();
a1.add(new Object());
a1.add(new Integer(10));
a1.add(new String("string"));
System.out.println("List is : " + a1);
List<?> a4 = a1;
a4.remove(0);
System.out.println("List is : " + a4);
System.out.println("List is : " + a4.get(0));
a4.clear();
System.out.println("List is : " + a4);
The result is :
List is : [java.lang.Object#2a139a55, 10, string]
List is : [10, string]
List is : 10
List is : []
Sounds like you should look for some documentation on Java generics.
The List<?> means that it is an object based on a currently unspecified type. That specification is made when the class is instantiated.
For example:
List<String> listOfStrings = new ArrayList<String>();
is a list of String objects.
List<?> stands for List<? extends Object> so in Collection<E> you will find containsAll(Collection<?> c) which allows you to write
List<Object> objs = Arrays.<Object>asList("one",2,3.14,4);
List<Integer> ints = Arrays.asList(2,4);
assert objs.containsAll(ints);//true
List is an interface you can implement yourself and also implemented by some of the Java collections, like Vector.
You can provide compile-time typing information using the angled brackets. The most generic type would be Object, which would be List<Object>. The <?> you see is indicating a List of some subclass of Object or an Object. This is like saying List<? extends Object>, or List<? extends Foo>, where the List contains objects of some subclass of Foo or objects of Foo itself.
You can't instantiate a List; it's an interface, not an implementation.
When you take an element out of a Collection, you must cast it to the type of element that is stored in the collection. Besides being inconvenient, this is unsafe. The compiler does not check that your cast is the same as the collection's type, so the cast can fail at run time.
Generics provides a way for you to communicate the type of a collection to the compiler, so that it can be checked. Once the compiler knows the element type of the collection, the compiler can check that you have used the collection consistently and can insert the correct casts on values being taken out of the collection.
chk dis pdf
? is nothing but Wildcard in Generics
There are 3 different kind of Wildcards in Generics
1) Upper Bounded Wildcards: Uses extends key word
eg: List<? extends SuperClass>
2) Lower Bounded Wildcards
eg:Uses Super key word List<? super SubClass>
3) Unbounded Wildcard
List<?> list
List<?> is equivalent to List<? extends Object>
The wildcard ? extends Object is equivalent to the unbounded wildcard ?
<?> in java specification
Generics in java specification
You are probably looking at the template based List class. You can create a list of strings by List<String> myList = new MyList<String>(); as an example. Check the documentation for all the types it supports. It should support any object type, but if there is a sort functionality you have to supply some compare functions.
Note that in the example above MyList is a concrete class that implements the List interface in Java. It can be ArrayList.
EDIT:
I assumed List as a concrete class by mistake. Fixed the error above. Thanks Jon.

How many legal ways are there to create an instance of set/list/map with and without Generics

I am a bit confused about instance creating since I started to learn Generics because I realize for example, you can create a HashMap like this,
HashMap hashmap = new HashMap();
but also,
HashMap<String,String> hashmap = new HashMap<String, String>();
While I can also declare instance hashmap like this since HashMap is implemented from Map Interface
Map<String,String> hashmap = new HashMap<String, String>();
But if above is true, then I can also create instance of ArrayList this way, is it right?
List<String> arraylist = new ArrayList<String>();
And, how about a custom defined one, lets say class Walk implemented from interface Move so to create an instance object of Walk I can use code like both,
Walk walk = new Walk();
Move walk = new Walk();
And these won't cause problems, are these two declarations the same? And is Implementation the key feature to enable the feature while how about class extended from another for exapmle, class Son extended from class Father, is this one legal then?
Father son = new Son();
Okay, so that's a lot of questions and stuff to talk about but I'll see how much I can cover in a short answer.
Generics in Collection Declarations.
Let's start with reasons to use generics in your declarations rather than not using them.
Take the following two declarations;
HashMap hashmap = new HashMap();
HashMap<String,String> hashmap = new HashMap<String, String>();
The first will accept any key/value combinations and you will have to manually use instanceof and casting to get the objects from the map because there is no guarantee that it will contain the object types you think it does.
The second uses generics in the declaration and ENSURES that only String keys and values will make their way into your HashMap instance at compile time. Also, when you call get(), you will have a String object returned automatically and will not have to check and cast it yourself. Unless you have a very good reason, you should always be using generics with your declarations.
Polymorphism in Collection Declarations.
Now onto polymorphism when declaring your collections. Take the following two examples;
List<String> sl = new ArrayList<String>();
ArrayList<String> sl2 = new ArrayList<String>();
The first is more flexible and could hold any custom List subclass that any method decides to return. This means that methods such as get() might return slightly different results depending on the List subclass it contains, or that the items in the List might be kept in a different order or such. Think about that for a moment. This gives you much greater flexibility but much fewer certainties.
If you absolutely want to make sure that your List is an ArrayList and so that variable's methods will always act in accordance to ArrayList (and will always use insertion order), then use the second example. Otherwise if you want to allow some flexibility in List type (for example if you want it to be able to take some ordered AND sorted lists) use the first.
I hope this helps, and I hope I didn't miss anything too important.
Here are some links for further reading from the official Java tutorials;
Official Generics tutorials.
Official Inheritance & Polymorphism tutorials.
What is a raw type and why shouldn't we use it?
Your first line, HashMap hashmap = new HashMap() works because you're using raw types. This will throw a compiler warning in more recent versions of Java, but it's perfectly valid syntax; it essentially means that you can store keys and values of any type, and you won't get a compiler error. (This answer discusses raw types in more detail).
The only difference between that and your second instantiation of HashMap is that you are providing some restrictions on what the types of your keys and values can be.
All the rest of your examples are related to inheritance. As long as the left-hand side of an object instantiation is more general than the right-hand side (i.e., the type of the right-hand side inherits from the type of the left-hand side), then there's no compiler error.
Part of your confusion seems to be about the difference between implementing an interface and extending a class. For this problem, there isn't a difference; you can instantiate either the same way.
Legal ways to create an instance of set/map/list with generics: (E is an object of some class)
List<E> arraylist = new ArrayList<E>();
Map<Integer,E> hashmap = new HashMap<Integer, E>();
LinkedList<E> list = new LinkedList<E>();
Generics can be defined using
Data types(Integer, Double, etc)
Reference variables
Array of reference variable,
List, Queue or even Map
With the help of generics, its easier because you wont have to type cast from Object type to the required type everywhere else in the program. Such as consider the program below:
(Legal ways to create an instance of set/map/list without generics)
public class ListDemo {
public static void main(String[] args) {
ArrayList courseList = new ArrayList();
courseList.add("Java");
courseList.add("J2EE");
courseList.add("Android");
courseList.add("Hibernate");
courseList.add("Spring");
System.out.println("Displaying the contents: ");
for (Object obj : courseList)
{
String courseName = (String)obj;
System.out.println(courseName);
}
}
}
If you observe, type casting to String from Object is needed. Therefore when same kind of data is to be stored in a list, its better to go for Generics.
Whereas consider the program below, where different kinds of data is to be stored onto a list. Then, the default Object type comes into use.
public class ListDemo {
public static void main(String[] args) {
ArrayList sampleList = new ArrayList();
sampleList.add("StackOverflow");
sampleList.add(12345);
sampleList.add(new Car (2014,"Hyundai","SantaFe"));
sampleList.add(23.234);
System.out.println("Displaying the contents: ");
for (Object obj : sampleList)
System.out.println(obj);
}
}
Also note that compiler gives a Type Safety warning "The method add(Object) belongs to the raw type ArrayList. References to generic type ArrayList should be parameterized"
Read more on Generics here.
This has nothing to with generics, it's all inheritance: A a = new B() is valid when:
B is A (e.g., A a = new A())
A is an ancestor of B (as in Father above)
B or one of its ancestors implement interface A (as in Map and List above)
This is true whether or not generics are used.
But if above is true, then I can also create instance of ArrayList this way, is it right?
Yes, and it's better because it hides the detail that it's an ArrayList.
And, how about a custom defined one, lets say class Walk implemented from interface Move so to create an instance object of Walk I can use code like both,
These aren't generic; they're just a typical class hierarchy. Generics are used for things like collections that you want to use for a specific data type.
And these won't cause problems, are these two declarations the same?
Nearly, only you're only exposing Move's methods with the second declaration. It's saying "here's a movement, but you don't need to know the details about which movement it is."
And is Implementation the key feature to enable the feature while how about class extended from another for exapmle,
Search around for Abstract Class vs. Interface. Part of it is the "is a" vs "can it" distinction, and part is that class inheritance lets you provide an implementation. The quick aside in the guy who created Java jokingly said he regretted adding inheritance, saying he favored interfaces and composition.
If you want a good example of classes vs. interfaces, look at Collection, List, and AbstractList. They're structured quite well, and you'll notice you rarely knowingly work with an AbstractList unless you're subclassing it.
class Son extended from class Father, is this one legal then?
Could be. If Father has the getChildren() method and Son has getFather() and getMother().

Java Generics syntax and calling a method on interface types such as List

What is reason behind supporting the syntax below on java 1.7
List<Integer> ints=new ArrayList<>();
What flexibility does it provide?
If we wanted ints to be of a different type we would explicitly cast it and it would throw an error if the conversion could not be performed.
I am also not clear on how exactly does this work.Since List is an interface how are we able to call a method on it
List<Integer> ints = Arrays.asList(1,2);
ints.get(1);
Since return type of asList() is static<T> List<T> it's okay to access a field of a static interface without any class providing an implementation of it.But how are we able to access a method on such an interface
The collections library has a lot of them like Collections.Sort()
Who provides the implementation of these methods?
Question 1
Using
List<Integer> ints=new ArrayList<>();
instead of
List<Integer> ints=new ArrayList<Integer>();
doesn't add any flexibility as they're exactly equivalent. The diamond (<>) indicates that we don't want the raw type but the obvious parameterized type.
Oracle describes it here :
In Java SE 7, you can substitute the parameterized type of the
constructor with an empty set of type parameters (<>):
It just makes the code a little less verbose, thus easier to read and maintain. This is probably more evident on Oracle's example :
Map<String, List<String>> myMap = new HashMap<>();
compared to
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
Question 2
Arrays.asList(1,2); returns an object from a concrete class implementing the List interface.
In Java 1.6, it's an instance of the fixed-size java.util.Arrays.ArrayList :
3354 public static <T> List<T> asList(T... a) {
3355 return new ArrayList<T>(a);
3356 }
but the important point is that an object always is of a concrete class implementing the methods its interfaces defines.
When you're doing Collections.sort(, you're not using the Collection interface but the Collections class which contains this very concrete code :
132 public static <T extends Comparable<? super T>> void sort(List<T> list) {
133 Object[] a = list.toArray();
134 Arrays.sort(a);
135 ListIterator<T> i = list.listIterator();
136 for (int j=0; j<a.length; j++) {
137 i.next();
138 i.set((T)a[j]);
139 }
140 }
You have a number of questions in your question.
Generics provide compile-time checking whereas casting errors are not discovered until runtime.
Your ints is an object that supports the List interface so it is valid to call methods on it.
These are compile time checks, and are designed to ensure consistency, so implementations don't have to 'do' anything specific so long as they follow the rules laid down by the generics notation (e.g. for a method called with an object of type T, you only return something also of the same type T).
As has been pointed out, the diamond notation was brought in when it became clear that specifying a type in a constructor was unnecessarily verbose - the type can be clearly inferred (both by anyone reading the code, and by the compiler) from the target of the constructor.
List<Integer> ints=new ArrayList<>();
Its Generics easy to understand and Iterate
for(Integer intObj : ints ) {}
instead of
Iterator itr = ints.iterator() ;
while(itr.hasNext()) {
Integer intObj = (Integer) itr.next();
}
Since return type of Arrays.asList() is static?
Yes java.util.Arrays is an util class provides lots of utility methods.
But how are we able to access a method on such an interface?
Just view source code of ArrayList there you can find implementation methods from List interface.
Who provides the implementation of these methods?
The one who implement the interface like List Set etc
List<Integer> ints=new ArrayList<>();
is exactly the same as writing
List<Integer> ints=new ArrayList<Integer>();
It doesn't add flexibility, it just let you keep generics with your ArrayList whithout having to retype the type of the ArrayList, and so the ArrayList will not use raw type.
Some other thing is that writing this, you only get directly access to the List interface methods on your ArrayList object, event if these methods will have the behavior that is defined in the ArrayList class.
What flexibility does it provide?
It does not provide any flexibility; is just a syntactic sugaring. Kind of pointless since modern IDEs code completion already do that.
Since return type of asList() is static List it's okay to access a field of a static interface without any class providing an implementation of it.But how are we able to access a method on such an interface The collections library has a lot of them like Collections.Sort() Who provides the implementation of these methods?
The return type of asList() is List; the type has nothing to do with the fact that the method is static. Arrays is a class, not an interface, and asList() method is implemented there; the JDK provides the implementation.

Casting HashMap of subtypes to HashMap of supertypes

I do have troubles manipulating hashmaps. My problem is quite simple, but I cannot make it work...
I have an interface named MultilineWritable. My classes that do need to be marshalled on flat files do implement this interface, which define a String toFlatFormat() function and its opposite init(String flatFormat).
Now imagine that the Contract class do implement MultilineWritable and is identified by integers while the Person class do also implement this interface but is identified by Strings.
My function to marshall the HashMaps of contracts and persons looks like :
public void marshall(HashMap<Object, MultilineWritable>){}
My problem is I cannot find a way to cast a HashMap<String, Person> to a HashMap<Object, MultilineWritable>, even if String extends Object and Person extends MultilineWritable. Same for the casting of a HashMap<Integer, Contract>... consequently I cannot call my generic function.
Thx for any help regarding this problem.
Assuming your marshall method only ever reads values, you should just change the declaration to:
public void marshall(HashMap<?, ? extends MultilineWritable> map)
The problem is that if the existing method call were allowed, it could try to put any MultilineWritable into the map - even if it was the wrong map type:
Map<String, Person> map = new HashMap<String, Person>();
// What would you want map.put("foo", new Contact()) to do inside marshall?
marshall(map);
EDIT: For more details about wildcards, see the Java Generics FAQ.
What you are trying to do is to pass a specific type into a generic type. You need to use java's generics feature. Generics offer compile time safety only, so while you are allowed to pass specific types into a function that takes genetic type, you are not allowed to modify the collection or the map.
So in short your anser is:
public void marshall(HashMap<? extends Object, ? extends MultilineWritable> map)
In Java Generics are not Covariant. So you cannot do following
List<Integer> numList = new ArrayList<Integer>();
List<Number> numList = new ArrayList<Number>();
numList = numList; //Error
numList = (List<Number>)intList; //error
Generics are used by the compiler to typsafety. The actual type information (of the collections i.e. this is List of Integers) etc is lost at runtime.

Instantiating a Generic Class of Type <?>

I'm studying for the SCJP/OCPJP and I came across a sample question that seams strange to me.
The sample code instantiated two generic collections:
List<?> list = new ArrayList<?>();
List<? extends Object> list2 = new ArrayList<? extends Object>();
The "correct" answer to the question was that this code would compile but adding to either collection would produce a runtime error.
When I try to compile code like this I just get errors. The Java tutorial does not even show this type of code, it instead usually uses wildcards as a part of an upcast.
Collection<?> c = new ArrayList<String>();
Are the two generic collections above even legitimate code? The second by my logic would only disallow interfaces. The first one looks completely useless. Why use a generic that makes no attempt at control?
Check out the excellent Java generics tutorial PDF. More specifically the section about wildcards contains the answer to your question, and I quote
Collection<?> c = new ArrayList<String>();
c.add( new Object() );
Since we don’t know what the element type of c stands for, we cannot
add objects to it. The add() method takes arguments of type E, the
element type of the collection. When the actual type parameter is ?,
it stands for some unknown type. Any parameter we pass to add would
have to be a subtype of this unknown type. Since we don’t know what
type that is, we cannot pass anything in. The sole exception is null,
which is a member of every type.
If you want to declare Type at runtime, you can do something like this:
public class Clazz1<T> {
private final List<T> list = new ArrayList<T>();
private List<T> getList() {
return list;
}
/**
* #param args
*/
public static void main(String[] args) {
Clazz1<Integer> clazzInt = new Clazz1<Integer>();
clazzInt.getList().add(2);
System.out.println(clazzInt.getList());
Clazz1<String> clazzString = new Clazz1<String>();
clazzString.getList().add("test");
System.out.println(clazzString.getList());
}
}
I answered this somewhat before in this answer. ? cannot be used in the instantiation. I'm not sure why it says the code would compile, none of the java compilers I have used would allow that. You could do what is shown above by the following:
List<?> list = new ArrayList();
That would compile and run, but you couldn't do:
list.add("hello world"); //This wouldn't compile
new produces a concrete instance of an object. The concrete instance can have only one type, including any generics. Knowing this, wildcards cannot work with new.

Categories

Resources