Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Question about returning generics

Reply
Thread Tools

Question about returning generics

 
 
aaronfude@gmail.com
Guest
Posts: n/a
 
      02-04-2007
Hi,

Suppose I have an array of diverse types and I want extract all
objects of a certain type (e.g. Date) and return it as a vector of
that type. Is it possible to write a function that will return arrays
of different types depending on the input parameters. I guess I have
just about answered my own question negatively, but I'm hoping for
something like this:

Vector<Date> dates = collect(set, Date.class);
Vector<Double> doubles = collect(set, Double.class);

Not possible, right?

Thanks!

Aaron Fude

 
Reply With Quote
 
 
 
 
Tom Hawtin
Guest
Posts: n/a
 
      02-04-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
>
> Suppose I have an array of diverse types and I want extract all
> objects of a certain type (e.g. Date) and return it as a vector of
> that type. Is it possible to write a function that will return arrays
> of different types depending on the input parameters. I guess I have
> just about answered my own question negatively, but I'm hoping for
> something like this:
>
> Vector<Date> dates = collect(set, Date.class);
> Vector<Double> doubles = collect(set, Double.class);


Arrays or Vectors.

> Not possible, right?


I don't see why it should be impossible.

public static <T> List<T> collect(
Iterable<?> items, Class<? extends T> target
) {
if (target.isPrimitive()) {
throw new IllegalArgumentException();
}
List<T> found = new java.util.ArrayList<T>();
for (Object item : items) {
if (target.isInstance(item)) {
found.add(item);
}
}
return found;
}

@SuppressWarnings("unchecked")
public static <T> T[] collect(
Iterable<?> items, Class<T> target
) {
List<T> found = collect(items, target);
return found.toArray((T[])
java.lang.reflect.Arrays.newInstance(target, found.size())
);
}

[Disclaimer: Not tested, or even compiled.]

I am not, however, convinced that this is a brilliant design.

Tom Hawtin
 
Reply With Quote
 
 
 
 
Mike Schilling
Guest
Posts: n/a
 
      02-04-2007

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> Hi,
>
> Suppose I have an array of diverse types and I want extract all
> objects of a certain type (e.g. Date) and return it as a vector of
> that type. Is it possible to write a function that will return arrays
> of different types depending on the input parameters. I guess I have
> just about answered my own question negatively, but I'm hoping for
> something like this:
>
> Vector<Date> dates = collect(set, Date.class);
> Vector<Double> doubles = collect(set, Double.class);
>



You want something like

static <T> Vector<T> collect(Collection c, Class<T> clazz)
{
Vector<T> v = new Vector<T>();
for (Object o : c)
{
if (clazz.isInstance(o))
v.add((T) o);
}
return v;
}

Class<T> is an idiom worth learning. The only member (other than null) of
the type Class<T> is T.class. If you're writing generic code and will need
access to the Class object for a parameterized type, having an argument of
type Class<T> is the way to get it.

Warning: I've compiled this but not tested it, so beware of subtle bugs.
Note also that isInstance() returns false for null arguments (like
instanceof does), so you'll never see null members in the Vector.


 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      02-04-2007
(E-Mail Removed) wrote:

> Suppose I have an array of diverse types and I want extract all
> objects of a certain type (e.g. Date) and return it as a vector of
> that type. Is it possible to write a function that will return arrays
> of different types depending on the input parameters.


Probably not a good idea to design your API in terms of raw arrays, nor to use
Vector (essentially obsolete, and has been for many years). But using
java.util.List it seems to work OK:

-- chris

======== Utils.java ============
import java.util.*;

public class Utils
{
public static <X>
List<X>
collect(List<Object> list, Class<X> clobj, boolean allowNull)
{
List<X> filtered = new ArrayList<X>();
for (Object elem : list)
{
if (allowNull && elem == null)
filtered.add(null);
else if (clobj.isInstance(elem))
filtered.add(clobj.cast(elem));
}
return filtered;
}
}
======== Test.java ============
import java.util.*;

public class Test
{
public static void
main(String[] args)
{
List<Object> all = Arrays.asList(new Object[] {
"one",
null,
true,
false,
'c',
88.88,
100
});

System.out.println("Strings (or null):");
List<String> strings = Utils.collect(all, String.class, true);
for (String s : strings)
System.out.println("\t" + s);

System.out.println("Numbers:");
List<Number> numbers = Utils.collect(all, Number.class, false);
for (Number n : numbers)
System.out.println("\t" + n);
}
}
=============================



 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      02-04-2007
I wrote:

> public static <X>
> List<X>
> collect(List<Object> list, Class<X> clobj, boolean allowNull)
> {


Come to think of it (and influenced in part by Tom's post), I think that:

public static <Super, Sub extends Super>
List<Sub>
collect(
List<? extends Super> list,
Class<Sub> clobj,
boolean allowNull)
{
List<Sub> filtered = new ArrayList<Sub>();
for (Super elem : list)
{
if (allowNull && elem == null)
filtered.add(null);
else if (clobj.isInstance(elem))
filtered.add(clobj.cast(elem));
}
return filtered;
}

is to be prefered.

Notice how the attempt to satisfy the compiler results in reams of code, no
real gain, and a distraction of attention from /non/ inessentials such as the
hardwired decision that the returned List as an ArrayList.

-- chris


 
Reply With Quote
 
Tom Hawtin
Guest
Posts: n/a
 
      02-04-2007
Chris Uppal wrote:
> I wrote:
>
>> public static <X>
>> List<X>
>> collect(List<Object> list, Class<X> clobj, boolean allowNull)
>> {

>
> Come to think of it (and influenced in part by Tom's post), I think that:
>
> public static <Super, Sub extends Super>
> List<Sub>
> collect(
> List<? extends Super> list,
> Class<Sub> clobj,
> boolean allowNull)
> {


> is to be prefered.


I certainly wouldn't want to insist on a List of Object. I'm not sure
what the point of 'Super' is there. Most code will not specify type
arguments for generic methods explicitly (wish the same was true for
types in constructors). Object will always be sufficient for 'Super'.

I don't like the allowNull parameter. I don't see what the point of
using it would be. The code would be simpler without it. And the calling
code would be more understandable without a strange boolean flag tagged
onto the end without explanation.

Also generic parameters. Can we have them in AOL? I spent ages the other
day trying to find where a pair of classes/interfaces were defined.
NetBeans just shrugged. Then I realised what they were. (OTOH, I
sometimes like multiple characters - EXC for exceptions and THIS for
self type).

> Notice how the attempt to satisfy the compiler results in reams of code, no
> real gain, and a distraction of attention from /non/ inessentials such as the
> hardwired decision that the returned List as an ArrayList.


Yes, but at least it is the method author who has to worry about it. And
hopefully the method will be used more often than it is implemented. A
programmer using the method doesn't need to concern his or herself about
it. Just see that it has been worked out, and the compiler will note any
misunderstanding.

Tom Hawtin
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
generics depending on generics Soul VHDL 0 02-02-2009 09:14 AM
returning none when it should be returning a list? randomtalk@gmail.com Python 11 05-02-2006 10:26 AM
Generics: factory method for returning parameterized instance allen@rrsg.ee.uct.ac.za Java 3 09-17-2005 07:16 AM
Generics and returning specific subclass from method sks Java 2 08-29-2005 11:16 AM
Can't convert a generics list of objects into a generics list ofinterfaces Juergen Berchtel Java 1 05-20-2005 02:07 PM



Advertisments