ArrayList called with specific object constructors

A

Alessandro

Hi all,

I have a method called xml2obj() returning a specific ArrayList
(ArrayList<Ric>), infact I call a specific constructor of Ric class
inside this method. I need to generalize this method for every kind of
object, not only Ric and calling of course their constructor.

I have some problems ... tried using generic ArrayList or
ArrayList<Object> but when calling the constructor I get error.
Constructor will have always this structure constr(String value1,
String value2)


This is the fragment which will be more clear:


// START
*** SPECIFIC METHOD xml2obj with ArrayList<Ric>***
....
public ArrayList<Ric> xml2obj(){
ArrayList<Ric> ricList=new ArrayList<Ric>();
....
ricList.add(new Ric(group,instrument);
return ricList;
}


*** class Ric ***
public class Ric {
private String group;
private String instrument;

//costr
public Ric(String group, String instrument) {
this.group = group;
this.instrument = instrument;
}

public String getGroup() {
return group;
}
public String getInstrument() {
return instrument;
}
}

*** idea of GENERIC METHOD in another class ***
....
public ArrayList<Object> xml2Obj(Document doc, Object obj) {
ArrayList myList=new ArrayList();
....
myList.add(new Object(name1,name2));

}

//END


Any suggestions ??

Thanks and best regards,
Alessandro
 
J

Joshua Cranmer

Alessandro said:
Hi all,

I have a method called xml2obj() returning a specific ArrayList
(ArrayList<Ric>), infact I call a specific constructor of Ric class
inside this method. I need to generalize this method for every kind of
object, not only Ric and calling of course their constructor.

I have some problems ... tried using generic ArrayList or
ArrayList<Object> but when calling the constructor I get error.
Constructor will have always this structure constr(String value1,
String value2)

This is obviously a use case for a factory. This stub should work:

public interface Factory<T> {
public T makeObject(String s1, String s2);
}

public <T> List<T> makeList(Factory<? extends T> factory) {
ArrayList<T> list = new ArrayList<T>();
/* ... */
list.add(factory.makeObject("whatever", "whatever x2");
return list;
}
 
Z

Zio Jerry

This is obviously a use case for a factory. This stub should work:
public interface Factory<T> {
   public T makeObject(String s1, String s2);

}

public <T> List<T> makeList(Factory<? extends T> factory) {
   ArrayList<T> list = new ArrayList<T>();
   /* ... */
   list.add(factory.makeObject("whatever", "whatever x2");
   return list;

}

Hi and thanks for your answer. I haven't ever used Factories before
and also I'm not expert about generalizations.
Anyway, your code seems pretty good but I have just a simple question:
why using "<? extends T>" instead of simply "<T>" ?

Will I have to create a superclass ? I wasn't thinking about creating
a superclass ...
 
L

Lew

Zio said:
Anyway, your code seems pretty good but I have just a simple question:
why using "<? extends T>" instead of simply "<T>" ?

The difference is that a 'List<T>' can contain many different subtypes
of 'T' in it, e.g., a 'List<Number>' can contain a mix of 'Double',
'BigInteger' and 'AtomicLong' instances. A 'List<? extends T>' can
contain only one type of entry, which must be a subtype of 'T'. Thus,
a 'List<? extends Number>' could contain all 'Double' entries, or all
'BigInteger' entries, but not both in the same list.

Read the sample chapter of Joshua Bloch's /Effective Java/ that covers
generics:
<http://java.sun.com/docs/books/effective/generics.pdf>
 
R

Robert Klemme

The difference is that a 'List<T>' can contain many different subtypes
of 'T' in it, e.g., a 'List<Number>' can contain a mix of 'Double',
'BigInteger' and 'AtomicLong' instances. A 'List<? extends T>' can
contain only one type of entry, which must be a subtype of 'T'. Thus,
a 'List<? extends Number>' could contain all 'Double' entries, or all
'BigInteger' entries, but not both in the same list.

Just a small note: Josh used the <? extends T> on the _factory_ and not
the _list_. Of course, the same reasoning as presented applies.

The reason to do it is greater flexibility, i.e. - translating the
example - not only factories with return type Number on the factory
method can be used but also factories for Integer, Double etc.
Read the sample chapter of Joshua Bloch's /Effective Java/ that covers
generics:
<http://java.sun.com/docs/books/effective/generics.pdf>

And one remark to the usage: with Josh's code you can nicely use an
anonymous class, e.g.

List<Foo> lst = makeList(new Factory<Foo>() {
Foo makeObject(String s1, String s2) {
return new Foo(s1, s2);
}
});

Whether that's reasonable or efficient depends of course on the context.

Kind regards

robert
 
J

Joshua Cranmer

Zio said:
Hi and thanks for your answer. I haven't ever used Factories before
and also I'm not expert about generalizations.
Anyway, your code seems pretty good but I have just a simple question:
why using "<? extends T>" instead of simply "<T>" ?

The idea is that you want to be able to use a factor of Integers (e.g.)
to fill a list of Numbers. The other way of doing this is to do this:
public <T> List<? super T> makeList(Factory<T> factory)

I prefer the other way.
 
Z

Zio Jerry

The idea is that you want to be able to use a factor of Integers (e.g.)
to fill a list of Numbers. The other way of doing this is to do this:
public <T> List<? super T> makeList(Factory<T> factory)

I prefer the other way.


That's clear, but I have problems using the interface Factory<T>

Also Robert code doesn't seem working because of course you can't
instantiate an interface:
List<Foo> lst = makeList(new Factory<Foo>() {
Foo makeObject(String s1, String s2) {
return new Foo(s1, s2);
}

});

This is my code adapted with your suggestions:

//START
*** class calling generic method (implements Factory ?? Factory<T> ??)
***
....
ArrayList<Ric> ricList=xmlService.xml2objGEN(new Factory<Ric>());
....

*** class with GENERIC METHOD xml2objGEN() ***
....
private <T> ArrayList<T> xml2objGEN(Factory<T> factory){
ArrayList<T> list=new ArrayList<T>();
list.add(factory.makeObject("value1,"value2"));
return list;
}
*** interface Factory ***
public interface Factory<T> {
public T makeObject(String s1, String s2);
}
//END



Thanks again,
Alessandro
 
Z

Zio Jerry

The idea is that you want to be able to use a factor of Integers (e.g.)
to fill a list of Numbers. The other way of doing this is to do this:
public <T> List<? super T> makeList(Factory<T> factory)

That's clear, but I have problems with calling the interface Factory.
Still viewed Robert code but it can't work because instantiating an
interface.

This is my edited fragment:

//START
*** Factory interface ***
public interface Factory<T> {
public T makeObject(String s1, String s2);
}

*** class calling generic method (implements Factory ??? implements
Factory<T> ???***
....
ArrayList<Ric> ricList=xmlService.xml2ListGEN(new Factory<Ric>());

*** class with generic method ***
private <T> ArrayList<T> xml2ListGEN(Factory<T> factory){

ArrayList<T> list=new ArrayList<T>();
list.add(factory.makeObject("value1","value2"));
return list;
}

*** Ric class was the same ***
//END

Please could you give just again a look ?

Thanks and best regards,
Alessandro
 
A

Alessandro

The idea is that you want to be able to use a factor of Integers (e.g.)
to fill a list of Numbers. The other way of doing this is to do this:
public <T> List<? super T> makeList(Factory<T> factory)


That's clear, but I have problems with calling the interface Factory.
Still viewed Robert code but it can't work because instantiating an
interface.

This is my edited fragment:

//START
*** Factory interface ***
public interface Factory<T> {
public T makeObject(String s1, String s2);
}

*** class calling generic method (implements Factory ??? implements
Factory<T> ???***
....
ArrayList<Ric> ricList=xmlService.xml2ListGEN(new Factory<Ric>());

*** class with generic method ***
private <T> ArrayList<T> xml2ListGEN(Factory<T> factory){

ArrayList<T> list=new ArrayList<T>();
list.add(factory.makeObject("value1","value2"));
return list;
}

*** Ric class was the same ***
//END

Please could you give just again a look ?

Thanks and best regards,
Alessandro
 
L

Lew

Alessandro said:
That's clear, but I have problems with calling the interface Factory.
Still viewed Robert code but it can't work because instantiating an
interface.

You don't instantiate interfaces. You instantiate a concrete class and assign
its reference to an interface-typed variable.
This is my edited fragment:

//START
*** Factory interface ***
public interface Factory<T> {
public T makeObject(String s1, String s2);
}
*** class calling generic method (implements Factory ??? implements
Factory<T> ???***
...
ArrayList<Ric> ricList=xmlService.xml2ListGEN(new Factory<Ric>());

Nope. Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
public Ric makeObject( String s1, String s2 )
{
return new Ric( s1, s2 );
}
}
====
List <Ric> rics = makeList( new RicFactory() );
...
 
Z

Zio Jerry

You don't instantiate interfaces.  You instantiate a concrete class and assign
its reference to an interface-typed variable.



Nope.  Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...


Many thanks, now that's all clear and working !
Thanks also to all people have contributed about this post.

Alessandro
 
Z

Zio Jerry

You don't instantiate interfaces.  You instantiate a concrete class and assign
its reference to an interface-typed variable.



Nope.  Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...


Many thanks Lew for your code, now that's all clear !!
And thanks also to all the people have contributed to this post.

Alessandro
 
Z

Zio Jerry

Nope.  Instead of 'new Factory said:
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...


Many thanks Lew for your code ! That's working fine now !
And thanks also to all the people have contributed about this post.

Alessandro
 
Z

Zio Jerry

You don't instantiate interfaces.  You instantiate a concrete class and assign
its reference to an interface-typed variable.



Nope.  Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...

Many thanks Lew for your code ! That's working fine now !
And thanks also to all the people have contributed about this post.

Alessandro
 
Z

Zio Jerry

You don't instantiate interfaces.  You instantiate a concrete class and assign
its reference to an interface-typed variable.



Nope.  Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...

Thanks for your code, it has solved all my problems !
Thanks also to all the people who has answered to this post.

Alessandro
 
Z

Zio Jerry

You don't instantiate interfaces.  You instantiate a concrete class and assign
its reference to an interface-typed variable.



Nope.  Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...

Thanks for your code, it has solved all my problems !
Thanks also to all the people who has answered to this post.

Alessandro
 
Z

Zio Jerry

You don't instantiate interfaces.  You instantiate a concrete class and assign
its reference to an interface-typed variable.



Nope.  Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...

Many thanks for your code, I have solved !
Thanks to the other people who have answered too.

Alessandro
 
Z

Zio Jerry

You don't instantiate interfaces.  You instantiate a concrete class and assign
its reference to an interface-typed variable.



Nope.  Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...

Hi Lew,

thanks for your code, I have solved !
Thanks also to the other people who have answered.

Alessandro
 
P

pciampa

You don't instantiate interfaces.  You instantiate a concrete class and assign
its reference to an interface-typed variable.



Nope.  Instead of 'new Factory <Ric>()' try something like Robert Klemme's
anonymous class trick, or define a named class like:

public class RicFactory implements Factory <Ric>
{
   public Ric makeObject( String s1, String s2 )
   {
     return new Ric( s1, s2 );
   }}

====
  List <Ric> rics = makeList( new RicFactory() );
  ...

Thanks all for your suggestions, Alessandro solved the issue
 
L

Lew


Please do not quote sigs.
Many thanks Lew for your code ! That's working fine now !
And thanks also to all the people have contributed about this post.

Please, one post sufficed, already!
 

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,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top