Help on java generics

C

cidsaril

I am new to Java 5 Programming and I am facing an issue with Generics
as below

In my java application , My main class is as below (I have replicated
the original scenario in the test program here )

import java.util.ArrayList;

public class TestGeneric {
public static void main(String args[]) {

ArrayList al = new ArrayList ();
TestClass tc = new TestClass();
al = tc.getList();
System.out.println(al);

}
}


And the TestClass is as below

import java.util.ArrayList;

public class TestClass {

public ArrayList getList() {

ArrayList list1 = new ArrayList();
list1.add("Hello1");
list1.add("Hellow1");
ArrayList list2 = new ArrayList ();
list2.add("Hello2");
list2.add("Hellow2");
ArrayList list3 = new ArrayList ();

list3.add(list1);
list3.add(list2);
return list3;

}

}

The method getList in TestClass returns as ArrayList of ArrayLists .
If I need to implement the above two class using Generics , how Can I
go about it .

Will it be ArrayList <ArrayList > al = new ArrayList <ArrayList>
(); in the main program ? or
ArrayList <Object > al = new ArrayList <Object> ();
Please help

Thanks
Sam
 
D

Donkey Hot

(e-mail address removed) wrote in @h1g2000prh.googlegroups.com:
I am new to Java 5 Programming and I am facing an issue with Generics
as below

In my java application , My main class is as below (I have replicated
the original scenario in the test program here )

import java.util.ArrayList;

public class TestGeneric {
public static void main(String args[]) {

ArrayList al = new ArrayList ();
TestClass tc = new TestClass();
al = tc.getList();
System.out.println(al);

}
}


And the TestClass is as below

import java.util.ArrayList;

public class TestClass {

public ArrayList getList() {

ArrayList list1 = new ArrayList();
list1.add("Hello1");
list1.add("Hellow1");
ArrayList list2 = new ArrayList ();
list2.add("Hello2");
list2.add("Hellow2");
ArrayList list3 = new ArrayList ();

list3.add(list1);
list3.add(list2);
return list3;

}

}

The method getList in TestClass returns as ArrayList of ArrayLists .
If I need to implement the above two class using Generics , how Can I
go about it .

Will it be ArrayList <ArrayList > al = new ArrayList <ArrayList>
(); in the main program ? or
ArrayList <Object > al = new ArrayList <Object> ();
Please help

Thanks
Sam

ArrayList<ArrayList<String>>
 
D

Donkey Hot

(e-mail address removed) wrote in @h1g2000prh.googlegroups.com:
I am new to Java 5 Programming and I am facing an issue with Generics
as below

In my java application , My main class is as below (I have replicated
the original scenario in the test program here )

import java.util.ArrayList;

public class TestGeneric {
public static void main(String args[]) {

ArrayList al = new ArrayList ();
TestClass tc = new TestClass();
al = tc.getList();
System.out.println(al);

}
}


And the TestClass is as below

import java.util.ArrayList;

public class TestClass {

public ArrayList getList() {

ArrayList list1 = new ArrayList();
list1.add("Hello1");
list1.add("Hellow1");
ArrayList list2 = new ArrayList ();
list2.add("Hello2");
list2.add("Hellow2");
ArrayList list3 = new ArrayList ();

list3.add(list1);
list3.add(list2);
return list3;

}

}

The method getList in TestClass returns as ArrayList of ArrayLists .
If I need to implement the above two class using Generics , how Can I
go about it .

Will it be ArrayList <ArrayList > al = new ArrayList <ArrayList>
(); in the main program ? or
ArrayList <Object > al = new ArrayList <Object> ();
Please help

Thanks
Sam

ArrayList<ArrayList<String>>

Actually:

List<List<String>> al = new List<List<String>>() ;

ArrayList is the implementation, but you could use the interface List in
the variable declaration.
 
D

Donkey Hot

(e-mail address removed) wrote in @h1g2000prh.googlegroups.com:
I am new to Java 5 Programming and I am facing an issue with Generics
as below

In my java application , My main class is as below (I have replicated
the original scenario in the test program here )

import java.util.ArrayList;

public class TestGeneric {
public static void main(String args[]) {

ArrayList al = new ArrayList ();
TestClass tc = new TestClass();
al = tc.getList();
System.out.println(al);

}
}


And the TestClass is as below

import java.util.ArrayList;

public class TestClass {

public ArrayList getList() {

ArrayList list1 = new ArrayList();
list1.add("Hello1");
list1.add("Hellow1");
ArrayList list2 = new ArrayList ();
list2.add("Hello2");
list2.add("Hellow2");
ArrayList list3 = new ArrayList ();

list3.add(list1);
list3.add(list2);
return list3;

}

}

The method getList in TestClass returns as ArrayList of ArrayLists .
If I need to implement the above two class using Generics , how Can I
go about it .

Will it be ArrayList <ArrayList > al = new ArrayList <ArrayList>
(); in the main program ? or
ArrayList <Object > al = new ArrayList <Object> ();
Please help

Thanks
Sam

ArrayList<ArrayList<String>>

Actually:

List<List<String>> al = new List<List<String>>() ;

ArrayList is the implementation, but you could use the interface List in
the variable declaration.

Sorry :(

List<List<String>> al = new ArrayList<TreeList<String>>() ;
 
A

Andrea Francia

Donkey said:
List<List<String>> al = new ArrayList<TreeList<String>>() ;

This does not work.

This works:

List<? extends List<String>> al = new ArrayList<TreeList<String>>() ;
 
D

Donkey Hot

Andrea Francia <[email protected]
HERE.gmx.it> wrote in
This does not work.

This works:

List<? extends List<String>> al = new ArrayList<TreeList<String>>() ;

Wow. Well I'll be damned, because I'm still with 1.4.2 with my day work..:(

But still. TreeList does not "extend" List, it implements it. Generics is
hard. Maybe harder than C++ templates?
 
A

Arne Vajhøj

Donkey said:
Wow. Well I'll be damned, because I'm still with 1.4.2 with my day work..:(

But still. TreeList does not "extend" List, it implements it. Generics is
hard. Maybe harder than C++ templates?

Possible, but safer to use.

Arne
 
D

Daniel Pitts

Arne said:
Possible, but safer to use.

Arne
Actually, its easier than C++ templates, and less safe to use :)

C++ templates allow much more flexibility and expressiveness (you can
create a specialization, for example), but are therefor more complicated
and confusing.

Java Generics are simply extra run-time information that you can choose
to ignore at compile time, and therefor run the risk of runtime
ClassCastException (when used incorrectly), where C++ templates are
expressed and enforced at compile time, so you'll get a compiler error
isntead.

As for the OP's original question:
You probably want
List<List<String>> strings = new ArrayList<List<String>>();
strings.add(new ArrayList<String>());

Keep your interface as generic as possible. You might even consider
whether you truly need a List, or a Set, or even if you only care to
guarantee a Collection. A List should be used if ordering matters, a
Set if you don't want duplicates, and a Collection if the consumer
shouldn't care.
 
A

Arne Vajhøj

Daniel said:
Actually, its easier than C++ templates, and less safe to use :)

C++ templates allow much more flexibility and expressiveness (you can
create a specialization, for example), but are therefor more complicated
and confusing.

C++ templates can be very complex. But they can also be very simple. And
the simple ones does not have the Java "how do I get rid of this
warning" problems.
Java Generics are simply extra run-time information that you can choose
to ignore at compile time,

That description does not exactly match my understanding of type
erasure.
and therefor run the risk of runtime
ClassCastException (when used incorrectly), where C++ templates are
expressed and enforced at compile time, so you'll get a compiler error
isntead.

I can not right away think of a case where Java compile time check
is weaker than C++ compile time check.

Arne
 
D

Daniel Pitts

First, in-case I didn't make it clear, I'm not actually saying one is
better than the other. I think they both have advantages and
disadvantages. As well as the fact that they work better for the
context they're designed for, not the context of the other language :)
C++ templates can be very complex. But they can also be very simple. And
the simple ones does not have the Java "how do I get rid of this
warning" problems.


That description does not exactly match my understanding of type
erasure.
You're right, I meant to say it a different way, but it came out wrong.
I can not right away think of a case where Java compile time check
is weaker than C++ compile time check.

Arne
Java programmers can use raw types. Template parameters on classes are
never optional*, and so you always have compile-time static checking.


* default values can be optionally specified, but the value itself is
always there.
 
A

Arne Vajhøj

Java programmers can use raw types. Template parameters on classes are
never optional*, and so you always have compile-time static checking.

* default values can be optionally specified, but the value itself is
always there.

You mean ArrayList, HashMap in pre-1.5 syntax ?

Arne
 
D

Daniel Pitts

Arne said:
You mean ArrayList, HashMap in pre-1.5 syntax ?

Arne
I mean any raw type, but those are good examples.
In c++, you can't have a std::map without specifying key/value types.
Of course, you can't do that in Java and support legacy code.
 
A

Arne Vajhøj

I mean any raw type, but those are good examples.
In c++, you can't have a std::map without specifying key/value types. Of
course, you can't do that in Java and support legacy code.

Java choose to make <Object> default for backwards compatibility, but
you can specify a restriction on the template parameter so that is
not possible.

And C++ does have Object. It is called void*.

It is not exactly type safety that characterize this code:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
int iv = 123;
double xv = 123.456;
string sv = "ABC";
vector<void *> v;
v.push_back(&iv);
v.push_back(&xv);
v.push_back(&sv);
cout << *((int*)v[0]) << endl;
cout << *((double*)v[1]) << endl;
cout << *((string*)v[2]) << endl;
return 0;
}

But I admit that C++ does not default to void* like Java
default to Object.

The curse of backwards compatibility.

And you do get a warning on it.

Arne
 
D

Daniel Pitts

Arne said:
Java choose to make <Object> default for backwards compatibility, but
you can specify a restriction on the template parameter so that is
not possible.
List said:
And C++ does have Object. It is called void*.
Different concepts. void * an untyped pointer. Object is a base class.
They have similar uses, but are fundamentally different.
It is not exactly type safety that characterize this code:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
int iv = 123;
double xv = 123.456;
string sv = "ABC";
vector<void *> v;
v.push_back(&iv);
v.push_back(&xv);
v.push_back(&sv);
cout << *((int*)v[0]) << endl;
cout << *((double*)v[1]) << endl;
cout << *((string*)v[2]) << endl;
return 0;
}
This code is broken for many reasons. The chances of seeing this in
production code *should* be zero. For one thing, you should use
dynamic_cast, or using boost::any instead of void * :)
But I admit that C++ does not default to void* like Java
default to Object.

The curse of backwards compatibility.
Indeed. Thank god I can still compile Java 1.1 source code today :)
And you do get a warning on it.
Yes, you do.
 
H

Hendrik Maryns

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Donkey Hot schreef:
| |
|> |>
|>> (e-mail address removed) wrote in |>> @h1g2000prh.googlegroups.com:
|>>
|>>> I am new to Java 5 Programming and I am facing an issue with Generics
|>>> as below
|>>>
|>>> In my java application , My main class is as below (I have
| replicated
|>>> the original scenario in the test program here )
|>>>
|>>> import java.util.ArrayList;
|>>>
|>>> public class TestGeneric {
|>>> public static void main(String args[]) {
|>>>
|>>> ArrayList al = new ArrayList ();
|>>> TestClass tc = new TestClass();
|>>> al = tc.getList();
|>>> System.out.println(al);
|>>>
|>>> }
|>>> }
|>>>
|>>>
|>>> And the TestClass is as below
|>>>
|>>> import java.util.ArrayList;
|>>>
|>>> public class TestClass {
|>>>
|>>> public ArrayList getList() {
|>>>
|>>> ArrayList list1 = new ArrayList();
|>>> list1.add("Hello1");
|>>> list1.add("Hellow1");
|>>> ArrayList list2 = new ArrayList ();
|>>> list2.add("Hello2");
|>>> list2.add("Hellow2");
|>>> ArrayList list3 = new ArrayList ();
|>>>
|>>> list3.add(list1);
|>>> list3.add(list2);
|>>> return list3;
|>>>
|>>> }
|>>>
|>>> }
|>>>
|>>> The method getList in TestClass returns as ArrayList of ArrayLists .
|>>> If I need to implement the above two class using Generics , how Can I
|>>> go about it .
|>>>
|>>> Will it be ArrayList <ArrayList > al = new ArrayList <ArrayList>
|>>> (); in the main program ? or
|>>> ArrayList <Object > al = new ArrayList <Object> ();
|>>> Please help
|>>>
|>>> Thanks
|>>> Sam
|>>>
|>>>
|>> ArrayList<ArrayList<String>>
|>>
|>>
|> Actually:
|>
|> List<List<String>> al = new List<List<String>>() ;
|>
|> ArrayList is the implementation, but you could use the interface List
| in
|> the variable declaration.
|>
|>
|>
|
| Sorry :(
|
| List<List<String>> al = new ArrayList<TreeList<String>>() ;

No, you meant

List<List<String>> al = new ArrayList<List<String>>();

and then when you instantiate one of the lists to go into that
ArrayList, you can still choose between ArrayList and TreeList.

A more informative name than ‘al’ would be good, though.

H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFITQXpe+7xMGD3itQRAj6fAJ0XF//Y2Xw8PIikWWFg1EeUY5y6FQCeIKL8
VxZITRUh8+Pgc3LgtTDeztk=
=S14+
-----END PGP SIGNATURE-----
 
A

Arne Vajhøj

Daniel said:
List<Object> is not the same as a raw List.

True.

But for all the simple usage it is.
Different concepts. void * an untyped pointer. Object is a base class.
They have similar uses, but are fundamentally different.

Given the differences between Java and C++ I think they are as
close as they can be.
It is not exactly type safety that characterize this code:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
int iv = 123;
double xv = 123.456;
string sv = "ABC";
vector<void *> v;
v.push_back(&iv);
v.push_back(&xv);
v.push_back(&sv);
cout << *((int*)v[0]) << endl;
cout << *((double*)v[1]) << endl;
cout << *((string*)v[2]) << endl;
return 0;
}
This code is broken for many reasons. The chances of seeing this in
production code *should* be zero. For one thing, you should use
dynamic_cast, or using boost::any instead of void * :)

The example is a bit unrealistic.

But it is valid C++ so it does show that C++ templates
are not necessarily type safe.

Arne
 
R

Roedy Green

That description does not exactly match my understanding of type
erasure.

Generics are purely a compile time phenomenon. At run time there is
on type information, at least not in JDK 1.5 and 1.6. It may come in
1.7.
 
A

Arne Vajhøj

Roedy said:
Generics are purely a compile time phenomenon. At run time there is
on type information, at least not in JDK 1.5 and 1.6. It may come in
1.7.

Which is the opposite of what was written.

(and which Daniel also acknowledged that he got worded
wrong 2 weeks ago)

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top