Reputation: 21
I am trying to use java 8 stream. I checked the other posts and I do not understand why my code below is causing an error. Someone can tell me what is wrong with my code? Thank you
private OptList myFunction(OptList childOpts, Opt subOpt) {
OptList results = new OptList();
for (Opt o : childOpts) {
if ((subOpt.getOptPri() == null || subOpt.getOptPrices().isZeroPrice())
&& (o.getOptPrices() == null || o.getOptPrices().isZeroPrice()))
{
results.add(o);
} else
if (subOpt.getOptPrices() != null && o.getOptPrices() != null) {
if (subOpt.getOptPrices().getPrice(PriceType.MS).equals(o.getOptPrices().getPrice(PriceType.MS))
&& subOpt.getOptPrices().getPrice(PriceType.DISC).equals(o.getOptPrices().getPrice(PriceType.DISC))
&& subOpt.getOptPrices().getPrice(PriceType.INV).equals(o.getOptPrices().getPrice(PriceType.INV))
&& subOpt.getOptPrices().getPrice(PriceType.INV_DISC).equals(o.getOptPrices().getPrice(PriceType.INV_DISC)))
{
results.add(o);
}
}
}
return results;
}
private OptionList myFunction(OptList childOpts,
Opt subOpt) {
return childOpts.stream()
.filter(o -> (((subOpt.getOptPrices() == null || subOpt.getOptPrices().isZeroPrice()) && (o.getOptPrices() == null || o.getOptPrices().isZeroPrice()))
|| ( (subOpt.getOptPrices() != null && o.getOptPrices() != null) && (subOpt.getOptPrices().getPrice(PriceType.MS).equals(o.getOptPrices().getPrice(PriceType.MS))
&& subOpt.getOptPrices().getPrice(PriceType.DISC).equals(o.getOptPrices().getPrice(PriceType.DISC))
&& subOpt.getOptPrices().getPrice(PriceType.INV).equals(o.getOptPrices().getPrice(PriceType.INV))
&& subOpt.getOptPrices().getPrice(PriceType.INV_DISC).equals(o.getOptPrices().getPrice(PriceType.INV_DISC))) )))
.collect(Collectors.toList());
}
Upvotes: 0
Views: 967
Reputation: 9131
You are using your own List implementation.
Collectors.toList() does return a standard collection type: List<Opt>
.
Therefore your first option is to use the standard like
private List<yourType> myFunction(OptList childOpts, Opt subOpt)
or if OptionList
implements List
, then you are able to change your collect call to:
Collectors.toCollection(OptionList::new)
This little example provides some info on the returned types and standardtypes:
List<String> values = Arrays.asList("1", "2", "3");
System.out.println(
values.stream().collect(toList())
.getClass().getTypeName() );
System.out.println(
values.stream().collect(toCollection(LinkedList::new))
.getClass().getTypeName() );
It prints:
java.util.ArrayList
java.util.LinkedList
Upvotes: 0
Reputation: 6149
Let's look at the myFunction
method :
private OptionList myFunction(OptList childOpts, Opt subOpt) {
return childOpts.stream()
.filter(...)
.collect(Collectors.toList());
}
It takes a list of Opt
s (OptList
), eliminates those who don't match a certain criteria, then groups them back with the toList()
collector, which returns a java.util.List
of the items that are streamed.
So the expression's return type (and thus the whole method's return type) should be List<Opt>
or a supertype of it (eg. Collection<Opt>
).
Your current method signature is therefore wrong, and the compiler complains.
Upvotes: 0
Reputation: 8204
I understand that you have two functions, one implemented using regular collection operations, and the other implemented using streams, and you want to know why the second doesn't work.
I don't know what OptList
is, but it's not going to be a List<Opt>
, which is what collect(Collectors.toList())
is going to return. You need some way to make the collect
function return OptList
.
You have two options.
If OptList
is a (extends) Collection<Opt>
, then you can use toCollection
and pass an a function that produces an OptList:
childOpts.stream(). (other stuff) .collect(Collectors.toCollection(OptList::new))
This works because the collect
method knows how to call the add
method of the resulting Collection
.
If OptList
is not a collection type, then you can still use collect
, but you have to build your own collector. You will need to supply a function that creates the output type, a function to add a new member to it, and a function to combine two of the output types into one, which will be used if you are collecting parallel streams.
It will probably look something like this:
childOpts.stream(). (other stuff) .collect(OptList::new, OptList::add, OptList::addAll)
If OptList
doesn't have an addAll
, then you can try passing null
(not sure if that will work!) or passing a function that throws UnsupportedOperationException
.
Upvotes: 1