I am currently trying to learn how to use Generics from a book. In this chapter it says to take a piece of data T and convert it to an integer. I am trying different things
Hmm, that is an odd book. I'll try to tell you the gist of it based on what I know.
Generics are a construct that allow you compile-time check of whether a type you are trying to use in a specific collection, method, or class is actually something that knows the functionality that is necessary for that specific thing to function.
For example, you need to use the function determined by the interface called SearchParameter in your template, but you only see the <T>
parameter as an object. Or maybe a better example in your case would be a custom interface called IntegerConvert
like so:
public interface IntegerConvert
{
Integer returnAsInteger();
}
And you could have a class like this:
public class MyData implements IntegerConvert
{
private String data;
public MyData(String data)
{
this.data = data;
}
@Override
public Integer returnAsInteger()
{
return Integer.parseInt(data); //throws ParseException if it doesn't work
}
}
And then you could have a List of these like this:
List<IntegerConvert> listOfConvertibles = new ArrayList<IntegerConvert>();
or if you want to go a bit more generic for the future,
List<? extends IntegerConvert> listOfConvertibles = new ArrayList<IntegerConvert>();
and then you can do
listOfConvertibles.add("25");
listOfConvertibles.add("40");
listOfConvertibles.add("35");
for(IntegerConvert ic : listOfConvertibles)
{
System.out.println("" + ic.returnAsInteger());
}
Although that was a bit of an overcomplicated example, I guess. A simpler example would be the following:
public class Node<E>
{
private E data;
public Node(E e)
{
this.data = e;
}
public E getData()
{
return data;
}
public void setData(E e)
{
data = e;
}
public void print()
{
System.out.println(data.toString());
}
}
public class MyClass
{
public void doSomething()
{
List<Node<Float>> listOfFloatNodes = new ArrayList<Node<Float>>();
listOfFloatNodes.add(new Node<Float>(new Float(8.7472742f)));
listOfFloatNodes.add(new Node<Float>(new Float(5.56842742f)));
listOfFloatNodes.add(new Node<Float>(new Float(6.5467742f)));
MyOtherClass moc = new MyOtherClass();
moc.useNodeList(listOfFloatNodes);
}
}
public class MyOtherClass
{
public <E> void useNodeList(List<Node<E>> list)
{
for(Node<E> node : list)
{
printNode(node);
}
}
public <E> void printNode(Node<E> node)
{
node.print();
}
}
public class MainClass
{
public static void main(String[] args)
{
MyClass myClass = new MyClass();
myClass.doSomething();
}
}
If you have any questions, comment.
try to observe below examples:
public static void main(String[] args) {
test0("13");
test0(new Integer(13));
test1();
System.out.println(findValue(new Node("10")));
}
private static <T> void test0(T a) {
LinkedList<T> arr = new LinkedList<T>();
arr.add((T) a);
System.out.println(arr.getFirst());
}
private static <T> void test1() {
LinkedList<T> arr = new LinkedList<T>();
arr.add((T) new Integer(13));
System.out.println(arr.getFirst());
}
public static <T> int findValue(Node node) {
T data = (T) node.data;
int value = Integer.valueOf(data.toString());
return value;
}
where Node is :
public class Node {
//this should be private
public String data;
public Node(String data) {
this.data = data;
}
//use getter below to access private data
public String getData() {
return data;
}
}
all this is possible because, unchecked casts from a known type to T is allowed (of course with warnings) and compiler believes you for the casting.
Answer not entirely on the topic albeit closely related. I had a problem and didn't find the answer. Then I found solution and thought I'd share:
I was trying to cast generic value to primitive type:
<TYPE> boolean equal(TYPE val, Class<?> type) {
if (float.class == type) {
float val2 = (float) val; // incompatible types: TYPE cannot be converted to float
float val3 = (float) (Object) val; // works
...
Long story short: first version doesn't work and the second does. Quite annoying.