Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #27727 > unrolled thread
| Started by | zapanaz_googlegroups@hotmail.com |
|---|---|
| First post | 2014-03-11 09:36 -0700 |
| Last post | 2014-03-16 17:06 -0700 |
| Articles | 7 — 4 participants |
Back to article view | Back to comp.lang.java.programmer
Parameterized collection catch-22 zapanaz_googlegroups@hotmail.com - 2014-03-11 09:36 -0700
Re: Parameterized collection catch-22 markspace <markspace@nospam.nospam> - 2014-03-11 11:14 -0700
Re: Parameterized collection catch-22 zapanaz_googlegroups@hotmail.com - 2014-03-16 17:04 -0700
Re: Parameterized collection catch-22 Lew <lewbloch@gmail.com> - 2014-03-22 15:42 -0700
Re: Parameterized collection catch-22 zapanaz_googlegroups@hotmail.com - 2014-03-23 16:35 -0700
Re: Parameterized collection catch-22 Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2014-03-12 09:51 -0700
Re: Parameterized collection catch-22 zapanaz_googlegroups@hotmail.com - 2014-03-16 17:06 -0700
| From | zapanaz_googlegroups@hotmail.com |
|---|---|
| Date | 2014-03-11 09:36 -0700 |
| Subject | Parameterized collection catch-22 |
| Message-ID | <6f84734b-69d5-471c-b041-8d37dd5657e5@googlegroups.com> |
I have a parent class, AddressInfo. An abstract class. Two classes inherit from AddressInfo, ShippingInfo and BillingInfo. ShippingInfo and BillingInfo are nearly identical, and are identical for what I'm doing here.
The example code I'm posting is stripped down, in case you wonder why it's a little dumb.
I have two methods,
public void mergeBillingInfoLists(List<BillingInfo> list1, List<BillingInfo> list2) {
list1.add(1, list2.get(0));
}
And one for ShippingInfo which is identical, just with ShippingInfo where BillingInfo is.
I want to combine the two methods, which are very redundant. It seems like it should be possible, given that they have a common parent class. I can do this:
public void mergeAddressInfo(List<? extends AddressInfo> list1, List<? extends AddressInfo> list2) {
list1.add(1, list2.get(0));
}
But Java won't allow this, it won't allow the add(). All it knows about what list2 contains is that it's something that descends from AddressInfo, so even if I pass in 2 List<BillingInfo>'s, inside the code it doesn't know they're the same classes.
Does anybody offhand know a way to do this? (Without throwing away the parameterization :) )
I don't necessarily need to use this exact approach, just anything that would allow me to combine the two methods into one method. In fact I have quite a lot of this kind of redundancy in the code base I'm working with, so this is something I'm running into a lot.
Thanks for any help
--
Joe Cosby
http://joecosby.com/
`She knew how to embroider and milk a cow.' -- Connie Willis, Doomsday Book
:: Currently listening to Oxygene, Pt. II, 1976, by Jean Michel Jarre, from "Oxygene"
[toc] | [next] | [standalone]
| From | markspace <markspace@nospam.nospam> |
|---|---|
| Date | 2014-03-11 11:14 -0700 |
| Message-ID | <lfnjq6$t9m$1@dont-email.me> |
| In reply to | #27727 |
On 3/11/2014 9:36 AM, zapanaz_googlegroups@hotmail.com wrote:
> public void mergeAddressInfo(List<? extends AddressInfo> list1,
List<? extends AddressInfo> list2)
{
> list1.add(1, list2.get(0));
> }
>
> But Java won't allow this, it won't allow the add(). All it knows
> about what list2 contains is that it's something that descends from
> AddressInfo, so even if I pass in 2 List<BillingInfo>'s, inside the
> code it doesn't know they're the same classes.
Yes. Consider that your two subtypes, BillingInfo and ShippingInfo,
both match the wildcard <? extends AddressInfo>. So it's perfectly
legal to pass one of each to the mergeAddressInfo() method.
List<BillingInfo> b = ...;
List<ShippingInfo> s = ...;
x.mergeAddressInfo( b, s ); // works
So Java is telling you you can't call list1.add() because it assumes you
don't want to mix up a list of two different types.
So you have to tell the compiler that both parameters are of the same
type. One way to do that is to use a generic method:
public <A extends AddressInfo> void mergeAddressInfo( List<A> a,
List<A> b )
{...
Now the compiler knows that a and b are of the same type. It will
enforce that when you call the method (give you an error) and it will
allow operations that make sense for lists of the same type.
(Not compiled or tested.)
C.f. the Java tutorial.
<http://docs.oracle.com/javase/tutorial/java/generics/capture.html>
<http://docs.oracle.com/javase/tutorial/java/generics/methods.html>
[toc] | [prev] | [next] | [standalone]
| From | zapanaz_googlegroups@hotmail.com |
|---|---|
| Date | 2014-03-16 17:04 -0700 |
| Message-ID | <2fce5555-a057-4046-8fb1-de43d7175ece@googlegroups.com> |
| In reply to | #27729 |
On Tuesday, March 11, 2014 11:14:27 AM UTC-7, markspace wrote:
>
> public <A extends AddressInfo> void mergeAddressInfo( List<A> a,
>
> List<A> b )
>
> {...
>
>
>
> Now the compiler knows that a and b are of the same type. It will
>
> enforce that when you call the method (give you an error) and it will
>
> allow operations that make sense for lists of the same type.
>
Ah thanks very much. I should have known that.
They added generics to Java after I learned it, I still don't think of them.
>
>
> (Not compiled or tested.)
>
it's OK, I see what you're saying
--
Joe Cosby
Agent 99: Max, that knife missed you by inches.
Maxwell Smart: You think it's some kind of warning?
:: Currently listening to All My Life, 1972, by Uriah Heep, from "Demons and Wizards"
[toc] | [prev] | [next] | [standalone]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2014-03-22 15:42 -0700 |
| Message-ID | <1f8a0985-e157-4f91-b30e-0ff7da42c8c7@googlegroups.com> |
| In reply to | #27768 |
zapanaz_go...@hotmail.com wrote: > Ah thanks very much. I should have known that. > > They added generics to Java after I learned it, I still don't think of them. That was ten years ago. Two versions of Java have already gone obsolete since generics came in, and the fourth version to use them just came out. You might want to consider that it's been long enough. -- Lew
[toc] | [prev] | [next] | [standalone]
| From | zapanaz_googlegroups@hotmail.com |
|---|---|
| Date | 2014-03-23 16:35 -0700 |
| Message-ID | <cbc4a95e-2a76-4a92-9e6b-17321b8b01b1@googlegroups.com> |
| In reply to | #27814 |
On Saturday, March 22, 2014 3:42:58 PM UTC-7, Lew wrote: > zapanaz_go...@hotmail.com wrote: > > > Ah thanks very much. I should have known that. > > > > > > They added generics to Java after I learned it, I still don't think of them. > > > > That was ten years ago. Two versions of Java have already gone obsolete since generics came in, and the fourth version to use them just came out. > > > > You might want to consider that it's been long enough. > > > OK Dad
[toc] | [prev] | [next] | [standalone]
| From | Daniel Pitts <newsgroup.nospam@virtualinfinity.net> |
|---|---|
| Date | 2014-03-12 09:51 -0700 |
| Message-ID | <lg0Uu.13736$Nm1.6311@fx22.iad> |
| In reply to | #27727 |
On 3/11/14 9:36 AM, zapanaz_googlegroups@hotmail.com wrote:
> I have a parent class, AddressInfo. An abstract class. Two classes inherit from AddressInfo, ShippingInfo and BillingInfo. ShippingInfo and BillingInfo are nearly identical, and are identical for what I'm doing here.
>
> The example code I'm posting is stripped down, in case you wonder why it's a little dumb.
>
> I have two methods,
>
> public void mergeBillingInfoLists(List<BillingInfo> list1, List<BillingInfo> list2) {
> list1.add(1, list2.get(0));
> }
>
> And one for ShippingInfo which is identical, just with ShippingInfo where BillingInfo is.
>
> I want to combine the two methods, which are very redundant. It seems like it should be possible, given that they have a common parent class. I can do this:
>
> public void mergeAddressInfo(List<? extends AddressInfo> list1, List<? extends AddressInfo> list2) {
> list1.add(1, list2.get(0));
> }
>
> But Java won't allow this, it won't allow the add(). All it knows about what list2 contains is that it's something that descends from AddressInfo, so even if I pass in 2 List<BillingInfo>'s, inside the code it doesn't know they're the same classes.
>
> Does anybody offhand know a way to do this? (Without throwing away the parameterization :) )
>
> I don't necessarily need to use this exact approach, just anything that would allow me to combine the two methods into one method. In fact I have quite a lot of this kind of redundancy in the code base I'm working with, so this is something I'm running into a lot.
>
> Thanks for any help
>
There are three ways write that so it works as you desire:
Method one:
public <T> void mergeInfo(List<? super T> list1,List<? extends T> list2)
T is any type at all.
list1 can be any type of List of <T> or List of <SuperclassOfT> This
means the list1 can accept any object that is assignable *from* <T>. It
is unknown the type that it produces.
list2 can be any type of List of <T> or List of <SubclassOfT>. It will
produce objects that assignable *to* <T>.
Method two:
public <T> void mergeInfo(List<T> list1,List<? extends T> list2)
T is any type at all.
list1 can be any type of List of <T>, but not any other type parameter.
list1 can therefor produce and accept any object assignable to or from <T>
list2 is the same as list2 from Method One
Method three:
public <T> void mergeInfo(List<T> list1,List<T> list2)
T is any type at all.
list1 can be any type of List of <T>, but not any other type parameter.
list1 can therefor produce and accept any object assignable to or from <T>
list2 must be a List with the exact same type parameter as list1.
And finally, one last note. For any of the examples above, if you want
to ensure that you're only dealing with subclasses of AddressInfo:
public <T extends AddressInfo> void mergeInfo(... yata yata)
This says "T must be AddressInfo or a subclass thereof".
In your particular case, I would combine this with Method Three. Though
often with generic functions, you're better off with Method one.
The rule-of-thumb I use is: In your scope if you have an object that
only accepts <T> use <? super T>. If you have an object that only
produces <T>, use <? extends T>. If you have an object that produces
and accepts <T>, then use <T>. I'm talking about "produces" or
"accepts" in what you call, not what methods are available.
HTH.
[toc] | [prev] | [next] | [standalone]
| From | zapanaz_googlegroups@hotmail.com |
|---|---|
| Date | 2014-03-16 17:06 -0700 |
| Message-ID | <8bcf3da9-175d-4894-b80f-657d9f39afae@googlegroups.com> |
| In reply to | #27742 |
On Wednesday, March 12, 2014 9:51:33 AM UTC-7, Daniel Pitts wrote:
> On 3/11/14 9:36 AM, zapanaz_...@hotmail.com wrote:
>
> > I have a parent class, AddressInfo. An abstract class. Two classes inherit from AddressInfo, ShippingInfo and BillingInfo. ShippingInfo and BillingInfo are nearly identical, and are identical for what I'm doing here.
>
> >
>
> > The example code I'm posting is stripped down, in case you wonder why it's a little dumb.
>
> >
>
> > I have two methods,
>
> >
>
> > public void mergeBillingInfoLists(List<BillingInfo> list1, List<BillingInfo> list2) {
>
> > list1.add(1, list2.get(0));
>
> > }
>
> >
>
> > And one for ShippingInfo which is identical, just with ShippingInfo where BillingInfo is.
>
> >
>
> > I want to combine the two methods, which are very redundant. It seems like it should be possible, given that they have a common parent class. I can do this:
>
> >
>
> > public void mergeAddressInfo(List<? extends AddressInfo> list1, List<? extends AddressInfo> list2) {
>
> > list1.add(1, list2.get(0));
>
> > }
>
> >
>
> > But Java won't allow this, it won't allow the add(). All it knows about what list2 contains is that it's something that descends from AddressInfo, so even if I pass in 2 List<BillingInfo>'s, inside the code it doesn't know they're the same classes.
>
> >
>
> > Does anybody offhand know a way to do this? (Without throwing away the parameterization :) )
>
> >
>
> > I don't necessarily need to use this exact approach, just anything that would allow me to combine the two methods into one method. In fact I have quite a lot of this kind of redundancy in the code base I'm working with, so this is something I'm running into a lot.
>
> >
>
> > Thanks for any help
>
> >
>
>
>
> There are three ways write that so it works as you desire:
>
>
>
> Method one:
>
> public <T> void mergeInfo(List<? super T> list1,List<? extends T> list2)
>
>
>
> T is any type at all.
>
> list1 can be any type of List of <T> or List of <SuperclassOfT> This
>
> means the list1 can accept any object that is assignable *from* <T>. It
>
> is unknown the type that it produces.
>
>
>
> list2 can be any type of List of <T> or List of <SubclassOfT>. It will
>
> produce objects that assignable *to* <T>.
>
>
>
>
>
>
>
> Method two:
>
> public <T> void mergeInfo(List<T> list1,List<? extends T> list2)
>
>
>
> T is any type at all.
>
> list1 can be any type of List of <T>, but not any other type parameter.
>
> list1 can therefor produce and accept any object assignable to or from <T>
>
>
>
> list2 is the same as list2 from Method One
>
>
>
>
>
> Method three:
>
> public <T> void mergeInfo(List<T> list1,List<T> list2)
>
>
>
> T is any type at all.
>
> list1 can be any type of List of <T>, but not any other type parameter.
>
> list1 can therefor produce and accept any object assignable to or from <T>
>
>
>
> list2 must be a List with the exact same type parameter as list1.
>
>
>
>
>
> And finally, one last note. For any of the examples above, if you want
>
> to ensure that you're only dealing with subclasses of AddressInfo:
>
>
>
> public <T extends AddressInfo> void mergeInfo(... yata yata)
>
>
>
>
>
> This says "T must be AddressInfo or a subclass thereof".
>
>
>
> In your particular case, I would combine this with Method Three. Though
>
> often with generic functions, you're better off with Method one.
>
>
>
> The rule-of-thumb I use is: In your scope if you have an object that
>
> only accepts <T> use <? super T>. If you have an object that only
>
> produces <T>, use <? extends T>. If you have an object that produces
>
> and accepts <T>, then use <T>. I'm talking about "produces" or
>
> "accepts" in what you call, not what methods are available.
>
>
>
> HTH.
Thanks very much
--
Joe Cosby
Agent 99: Max, that knife missed you by inches.
Maxwell Smart: You think it's some kind of warning?
:: Currently listening to All My Life, 1972, by Uriah Heep, from "Demons and Wizards"
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web