Is it possible to create class, where e.g. second parameter is value?
Constructor would look something like this:
FancyClass<Integer, 1> myFancyClass = new FancyClass<>();
No. Generics are for types not for literal values.
I don't know what you're trying to do, but if there's some actual idea behind your code, you could easily implement it with
public class FancyClass<T> {
T myVal;
public FancyClass(T val) {
myVal = val;
}
}
FancyClass<Integer> myFancyClass = new FancyClass<>(1);
No. There's no logic in doing so anyway. From wikipedia:
Generics are a facility of generic programming that were added to the Java programming language in 2004 within J2SE 5.0. They allow a type or method to operate on objects of various types while providing compile-time type safety.
A small example:
The class Lunchbox represents a lunch box, which inside of it it's seperated into 2 different containers. Each "container" within the lunchbox can contain a bunch of items, but those items can be only of one (same) type.
Without generics, we would have to predefine 2 types for both sides of the containers. But lets say we wanted to do it so each Lunchbox can have different types of items. That's when we need generics:
public class Lunchbox<V1, V2>
Now inside the LunchBox class (and only inside the LunchBox class) you can access two types: V1 and V2. They're handeled like normal classes.
V1 objectOfTypeV1 = ...; //I can even declare variables with that type.
Now we can create lunchboxes of many kinds:
Lunchbox<String, Integer> lunchbox1 = new Lunchbox<>();//Contains strings and integers
Lunchbox<Foo, Bar> lunchbox2 = new Lunchbox<>();//Contains Foos and Bars
LunchBox<LunchBox<Foo, Bar>, Integer> lunchbox3 = new LunchBox<>(); //Contains lunchboxes (containing Foos and bars) and integers
For your question: If we were to put a value as a generic class, it wouldn't make any sense. Lets continue with the Lunchbox class - How can our lunchbox hold a type 1, when there is no such thing? You can't declare...
1 object = new 1();
That's not a class. That's a value. I don't understand why you'd want to put a value in a generic, and it doesn't make sense. Hope I helped.
Just in case you didn't understand anything from this, here's a link to Oracle where they have a lesson about generics, why to use them: Click here.
Why use generics? -Oracle
Related
I am currently studying Java and have recently been stumped by angle brackets(<>). What exactly do they mean?
public class Pool<T>{
public interface PoolFactory<T>{
public T createObject();
}
this.freeObjects = new ArrayList<T>(maxsize)
}
What does the <T> mean? Does it means that I can create an object of type T?
<T> is a generic and can usually be read as "of type T". It depends on the type to the left of the <> what it actually means.
I don't know what a Pool or PoolFactory is, but you also mention ArrayList<T>, which is a standard Java class, so I'll talk to that.
Usually, you won't see "T" in there, you'll see another type. So if you see ArrayList<Integer> for example, that means "An ArrayList of Integers." Many classes use generics to constrain the type of the elements in a container, for example. Another example is HashMap<String, Integer>, which means "a map with String keys and Integer values."
Your Pool example is a bit different, because there you are defining a class. So in that case, you are creating a class that somebody else could instantiate with a particular type in place of T. For example, I could create an object of type Pool<String> using your class definition. That would mean two things:
My Pool<String> would have an interface PoolFactory<String> with a createObject method that returns Strings.
Internally, the Pool<String> would contain an ArrayList of Strings.
This is great news, because at another time, I could come along and create a Pool<Integer> which would use the same code, but have Integer wherever you see T in the source.
It's really simple. It's a new feature introduced in J2SE 5. Specifying angular brackets after the class name means you are creating a temporary data type which can hold any type of data.
Example:
class A<T>{
T obj;
void add(T obj){
this.obj=obj;
}
T get(){
return obj;
}
}
public class generics {
static<E> void print(E[] elements){
for(E element:elements){
System.out.println(element);
}
}
public static void main(String[] args) {
A<String> obj=new A<String>();
A<Integer> obj1=new A<Integer>();
obj.add("hello");
obj1.add(6);
System.out.println(obj.get());
System.out.println(obj1.get());
Integer[] arr={1,3,5,7};
print(arr);
}
}
Instead of <T>, you can actually write anything and it will work the same way. Try writing <ABC> in place of <T>.
This is just for convenience:
<T> is referred to as any type
<E> as element type
<N> as number type
<V> as value
<K> as key
But you can name it anything you want, it doesn't really matter.
Moreover, Integer, String, Boolean etc are wrapper classes of Java which help in checking of types during compilation. For example, in the above code, obj is of type String, so you can't add any other type to it (try obj.add(1), it will cast an error). Similarly, obj1 is of the Integer type, you can't add any other type to it (try obj1.add("hello"), error will be there).
It is related to generics in java. If I mentioned ArrayList<String> that means I can add only String type object to that ArrayList.
The two major benefits of generics in Java are:
Reducing the number of casts in your program, thus reducing the number of potential bugs in your program.
Improving code clarity
is called a generic type. You can instantiate an object Pool like this:
PoolFactory<Integer> pool = new Pool<Integer>();
The generic parameter can only be a reference type. So you can't use primitive types like int or double or char or other primitive types.
<> is used to indicate generics in Java.
T is a type parameter in this example. And no: instantiating is one of the few things that you can't do with T.
Apart from the tutorial linked above Angelika Langers Generics FAQ is a great resource on the topic.
Generic classes are a type of class that takes in a data type as a parameter when it's created. This type parameter is specified using angle brackets and the type can change each time a new instance of the class is instantiated. For instance, let's create an ArrayList for Employee objects and another for Company objects
ArrayList<Employee> employees = new ArrayList<Employee>();
ArrayList<Company> companies = new ArrayList<Company>();
You'll notice that we're using the same ArrayList class to create both lists and we pass in the Employee or Company type using angle brackets. Having one generic class be able to handle multiple types of data cuts down on having a lot of classes that perform similar tasks.
Generics also help to cut down on bugs by giving everything a strong type which helps the compiler point out errors. By specifying a type for ArrayList, the compiler will throw an error if you try to add an Employee to the Company list or vice versa.
In Java, I can do that:
class JavaClass<A, B>{
A first;
B second;
}
And then declare an array, a list, or a single object of that type, without supplying generic parameters. They're being automatically converted to Object's, like in an example below:
JavaClass someArray = new JavaClass[4];
Now, the type of someArray[0].first is Object.
In C#, it doesn't seem to work:
class Leaderboard<UserType, UIEntry>
where UserType : User
where UIEntry : UserUIEntry{}
And the declaration:
Leaderboard someLeaderboard = new Leaderboard();
Gives:
Using the generic type Leaderboard requires two type arguments.
Is there any equivalent to make this work and allow me to declare that?
First of all, generics in C# and Java are very different, both conceptually and implementation-wise. C# has so-called reified generics, while Java uses type erasure. Therefore, looking for similarities between these two languages in generics is usually not a good idea.
In C#, Leaderboard and Leaderboard<UserType, UIEntry> are two distinct types. If you really want to, you can write
class Leaderboard<UserType, UIEntry>
where UserType : User
where UIEntry : UserUIEntry{}
class Leaderboard : Leaderboard<User, UserUIEntry>{}
and then use just new Leadeboard() (relying on inheritance). However, I wouldn’t think this is an especially great idea, trading a few keystrokes for worse readability.
Look how e.g. Tuple does it: Tuple is a nongeneric helper for the generic Tuple<...> class, containing a static .Create function which helps with type inference, reducing the need to write the generic parameters explicitly.
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().
I have seen declarations, interfaces and classes that go TYPE<CLASS>
What does this do/mean?
Without evidence, I believe you're talking about Java's Generics support...
Generics allow you to abstract over types
Before Java 5 it was difficult to provide classes that were capable of supporting multiple different types of Objects without having to code for each specific situation, so it was common for people to pass Object instead.
This leads to many difficult choices to make at runtime, you'd have to do a runtime check to see if it was possible to cast a given Object to a usable type...for example
List myIntList = new LinkedList(); // 1
myIntList.add(new Integer(0)); // 2
Integer x = (Integer) myIntList.iterator().next(); // 3
Now, this is reasonably obvious, but if you were passed just a List, you'd have to check each and every element in the list for correctness...
But now, we can do this...
List<Integer> myIntList = new LinkedList<Integer>(); // 1'
myIntList.add(new Integer(0)); // 2'
Integer x = myIntList.iterator().next(); // 3'
This is a contract that basically says "This list only contains Integer type's of objects".
With generics you can construct a single class that is capable of handling multiple different data types or a family of data types (ie constraint the parameter so that it must be extended from a particular parent type).
Iterator<? extends Number> itNum;
Basically says, this will contain objects that inherit from Number, include Integer, Long, Double, Float...
Often in method and class decelerations you will see something similar to...
public class MyGenericClass<T> {...}
or
public class MyGenericClass<T extends MyBaseObject> {...}
This allows you to refer to T as if it were a concrete object type, for example...
public class MyGenericClass<T extends MyBaseObject> {
private T value;
public MyGenericClass(T value) {
this.value = value;
}
}
This allows the compiler (and JVM) to essentially "replace" the marker T with a concert type (okay, it's a little more complicated then that, but that's the magic)...
This allows to do things like...
... new MyGenericClass<MySuperObject>(new MySuperObject());
... new MyGenericClass<MySuperSuperObject>(new MySuperSuperObject());
And know that it will only ever accept the type of object I specify...
Have a read through the link in the first paragraph, I'm sure it can do more justice then I can ;)
public class Grid<E> {
That's how you define a generic class in Java.Grid is the class and E is a formal type parameter.
If you are really interested in learning about it, you will find a very good reference here - Java Generics FAQs - Frequently Asked Questions
that is generic types check it here.
Simple examples would be
List<String>
Map<Integer, String>
It's unclear what you are asking without looking at what exactly you are seeing. But it's likely you are seeing Generics in Java. Learn more about it here
The idea is basically to make stronger type-safety in Java. So, a declaration like List<Integer> intList means intList has Integers in it. And if you try to put a, say, String -- it will throw compilation error.
I am currently studying Java and have recently been stumped by angle brackets(<>). What exactly do they mean?
public class Pool<T>{
public interface PoolFactory<T>{
public T createObject();
}
this.freeObjects = new ArrayList<T>(maxsize)
}
What does the <T> mean? Does it means that I can create an object of type T?
<T> is a generic and can usually be read as "of type T". It depends on the type to the left of the <> what it actually means.
I don't know what a Pool or PoolFactory is, but you also mention ArrayList<T>, which is a standard Java class, so I'll talk to that.
Usually, you won't see "T" in there, you'll see another type. So if you see ArrayList<Integer> for example, that means "An ArrayList of Integers." Many classes use generics to constrain the type of the elements in a container, for example. Another example is HashMap<String, Integer>, which means "a map with String keys and Integer values."
Your Pool example is a bit different, because there you are defining a class. So in that case, you are creating a class that somebody else could instantiate with a particular type in place of T. For example, I could create an object of type Pool<String> using your class definition. That would mean two things:
My Pool<String> would have an interface PoolFactory<String> with a createObject method that returns Strings.
Internally, the Pool<String> would contain an ArrayList of Strings.
This is great news, because at another time, I could come along and create a Pool<Integer> which would use the same code, but have Integer wherever you see T in the source.
It's really simple. It's a new feature introduced in J2SE 5. Specifying angular brackets after the class name means you are creating a temporary data type which can hold any type of data.
Example:
class A<T>{
T obj;
void add(T obj){
this.obj=obj;
}
T get(){
return obj;
}
}
public class generics {
static<E> void print(E[] elements){
for(E element:elements){
System.out.println(element);
}
}
public static void main(String[] args) {
A<String> obj=new A<String>();
A<Integer> obj1=new A<Integer>();
obj.add("hello");
obj1.add(6);
System.out.println(obj.get());
System.out.println(obj1.get());
Integer[] arr={1,3,5,7};
print(arr);
}
}
Instead of <T>, you can actually write anything and it will work the same way. Try writing <ABC> in place of <T>.
This is just for convenience:
<T> is referred to as any type
<E> as element type
<N> as number type
<V> as value
<K> as key
But you can name it anything you want, it doesn't really matter.
Moreover, Integer, String, Boolean etc are wrapper classes of Java which help in checking of types during compilation. For example, in the above code, obj is of type String, so you can't add any other type to it (try obj.add(1), it will cast an error). Similarly, obj1 is of the Integer type, you can't add any other type to it (try obj1.add("hello"), error will be there).
It is related to generics in java. If I mentioned ArrayList<String> that means I can add only String type object to that ArrayList.
The two major benefits of generics in Java are:
Reducing the number of casts in your program, thus reducing the number of potential bugs in your program.
Improving code clarity
is called a generic type. You can instantiate an object Pool like this:
PoolFactory<Integer> pool = new Pool<Integer>();
The generic parameter can only be a reference type. So you can't use primitive types like int or double or char or other primitive types.
<> is used to indicate generics in Java.
T is a type parameter in this example. And no: instantiating is one of the few things that you can't do with T.
Apart from the tutorial linked above Angelika Langers Generics FAQ is a great resource on the topic.
Generic classes are a type of class that takes in a data type as a parameter when it's created. This type parameter is specified using angle brackets and the type can change each time a new instance of the class is instantiated. For instance, let's create an ArrayList for Employee objects and another for Company objects
ArrayList<Employee> employees = new ArrayList<Employee>();
ArrayList<Company> companies = new ArrayList<Company>();
You'll notice that we're using the same ArrayList class to create both lists and we pass in the Employee or Company type using angle brackets. Having one generic class be able to handle multiple types of data cuts down on having a lot of classes that perform similar tasks.
Generics also help to cut down on bugs by giving everything a strong type which helps the compiler point out errors. By specifying a type for ArrayList, the compiler will throw an error if you try to add an Employee to the Company list or vice versa.