How 2 lists can be joined using streams and 1.8 functions? The Next CEO of Stack OverflowHow can I concatenate two arrays in Java?How do I join two lists in Java?How can I initialise a static Map?How can I create an executable JAR with dependencies using Maven?How can I convert a stack trace to a string?How to Convert a Java 8 Stream to an Array?How to convert an iterator to a stream?How can I turn a List of Lists into a List in Java 8?How can I throw CHECKED exceptions from inside Java 8 streams?How to sum a list of integers with java streams?

Rotate a column

Natural language into sentence logic

Whats the best way to handle refactoring a big file?

Trouble understanding the speech of overseas colleagues

Too much space between section and text in a twocolumn document

% symbol leads to superlong (forever?) compilations

What is the difference between "behavior" and "behaviour"?

How to count occurrences of text in a file?

Why didn't Khan get resurrected in the Genesis Explosion?

Does the Brexit deal have to be agreed by both Houses?

What is the purpose of the Evocation wizard's Potent Cantrip feature?

How do I construct this japanese bowl?

Fastest way to shutdown Ubuntu Mate 18.10

Why didn't Theresa May consult with Parliament before negotiating a deal with the EU?

Why do professional authors make "consistency" mistakes? And how to avoid them?

How to make a software documentation "officially" citable?

Does it take more energy to get to Venus or to Mars?

India just shot down a satellite from the ground. At what altitude range is the resulting debris field?

How can I quit an app using Terminal?

What makes a siege story/plot interesting?

Only print output after finding pattern

How long to clear the 'suck zone' of a turbofan after start is initiated?

Why here is plural "We went to the movies last night."

Science fiction (dystopian) short story set after WWIII



How 2 lists can be joined using streams and 1.8 functions?



The Next CEO of Stack OverflowHow can I concatenate two arrays in Java?How do I join two lists in Java?How can I initialise a static Map?How can I create an executable JAR with dependencies using Maven?How can I convert a stack trace to a string?How to Convert a Java 8 Stream to an Array?How to convert an iterator to a stream?How can I turn a List of Lists into a List in Java 8?How can I throw CHECKED exceptions from inside Java 8 streams?How to sum a list of integers with java streams?










2















I have a List of Prices and PriceGroups.



static class PriceGroup 
String priceName;
String priceGroup;


static class Price
String priceName;
Integer price;



Below is some sample data, and an implementation I wrote finding the lowest Price for each PriceGroup. Any suggestions how I could refactor this to utilize streams to join this data?



List<PriceGroup> priceGroups = Arrays.asList(
new PriceGroup("F1", "Friends"),
new PriceGroup("F2", "Friends"),
new PriceGroup("O1", "Others"),
new PriceGroup("O2", "Others"));

List<Price> prices = Arrays.asList(
new Price("F1", 100),
new Price("F2", 150),
new Price("O1", 250),
new Price("O2", 300));

public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices)

Map<String, Integer> bestPrice = new HashMap<String, Integer>();
for (PriceGroup priceGroup : priceGroups)
if (bestPrice.get(priceGroup.priceGroup) == null)
bestPrice.put(priceGroup.priceGroup, 10000000);


for (Price price : prices)
if (price.priceName.equals(priceGroup.priceName))
bestPrice.put(priceGroup.priceGroup, Math.min(price.price, bestPrice.get(priceGroup.priceGroup)));




return bestPrice;



For the given data, my function should return a map with:




F1 => 100

O1 => 250











share|improve this question



















  • 2





    at first, please make your code compile. new PriceGroup("F1", 100) won't work.

    – Markus Mitterauer
    Mar 7 at 14:08











  • List Prices should not be populated with PriceGroup objects - please correct your typo.

    – PM 77-1
    Mar 7 at 14:10











  • Sorry, corrected.

    – ab11
    Mar 7 at 14:11











  • second, I think Map<String, Price> prices and Map<String, PriceGroup> priceGroups would suite your problem better, because you could access the elements by name, instead of iterating over them.

    – Markus Mitterauer
    Mar 7 at 14:12











  • possibly, I wrote this only to ask the question of what is the java1.8 way of joining two lists on an id, and finding some minimum value from another list based on that id.

    – ab11
    Mar 7 at 14:13















2















I have a List of Prices and PriceGroups.



static class PriceGroup 
String priceName;
String priceGroup;


static class Price
String priceName;
Integer price;



Below is some sample data, and an implementation I wrote finding the lowest Price for each PriceGroup. Any suggestions how I could refactor this to utilize streams to join this data?



List<PriceGroup> priceGroups = Arrays.asList(
new PriceGroup("F1", "Friends"),
new PriceGroup("F2", "Friends"),
new PriceGroup("O1", "Others"),
new PriceGroup("O2", "Others"));

List<Price> prices = Arrays.asList(
new Price("F1", 100),
new Price("F2", 150),
new Price("O1", 250),
new Price("O2", 300));

public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices)

Map<String, Integer> bestPrice = new HashMap<String, Integer>();
for (PriceGroup priceGroup : priceGroups)
if (bestPrice.get(priceGroup.priceGroup) == null)
bestPrice.put(priceGroup.priceGroup, 10000000);


for (Price price : prices)
if (price.priceName.equals(priceGroup.priceName))
bestPrice.put(priceGroup.priceGroup, Math.min(price.price, bestPrice.get(priceGroup.priceGroup)));




return bestPrice;



For the given data, my function should return a map with:




F1 => 100

O1 => 250











share|improve this question



















  • 2





    at first, please make your code compile. new PriceGroup("F1", 100) won't work.

    – Markus Mitterauer
    Mar 7 at 14:08











  • List Prices should not be populated with PriceGroup objects - please correct your typo.

    – PM 77-1
    Mar 7 at 14:10











  • Sorry, corrected.

    – ab11
    Mar 7 at 14:11











  • second, I think Map<String, Price> prices and Map<String, PriceGroup> priceGroups would suite your problem better, because you could access the elements by name, instead of iterating over them.

    – Markus Mitterauer
    Mar 7 at 14:12











  • possibly, I wrote this only to ask the question of what is the java1.8 way of joining two lists on an id, and finding some minimum value from another list based on that id.

    – ab11
    Mar 7 at 14:13













2












2








2


1






I have a List of Prices and PriceGroups.



static class PriceGroup 
String priceName;
String priceGroup;


static class Price
String priceName;
Integer price;



Below is some sample data, and an implementation I wrote finding the lowest Price for each PriceGroup. Any suggestions how I could refactor this to utilize streams to join this data?



List<PriceGroup> priceGroups = Arrays.asList(
new PriceGroup("F1", "Friends"),
new PriceGroup("F2", "Friends"),
new PriceGroup("O1", "Others"),
new PriceGroup("O2", "Others"));

List<Price> prices = Arrays.asList(
new Price("F1", 100),
new Price("F2", 150),
new Price("O1", 250),
new Price("O2", 300));

public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices)

Map<String, Integer> bestPrice = new HashMap<String, Integer>();
for (PriceGroup priceGroup : priceGroups)
if (bestPrice.get(priceGroup.priceGroup) == null)
bestPrice.put(priceGroup.priceGroup, 10000000);


for (Price price : prices)
if (price.priceName.equals(priceGroup.priceName))
bestPrice.put(priceGroup.priceGroup, Math.min(price.price, bestPrice.get(priceGroup.priceGroup)));




return bestPrice;



For the given data, my function should return a map with:




F1 => 100

O1 => 250











share|improve this question
















I have a List of Prices and PriceGroups.



static class PriceGroup 
String priceName;
String priceGroup;


static class Price
String priceName;
Integer price;



Below is some sample data, and an implementation I wrote finding the lowest Price for each PriceGroup. Any suggestions how I could refactor this to utilize streams to join this data?



List<PriceGroup> priceGroups = Arrays.asList(
new PriceGroup("F1", "Friends"),
new PriceGroup("F2", "Friends"),
new PriceGroup("O1", "Others"),
new PriceGroup("O2", "Others"));

List<Price> prices = Arrays.asList(
new Price("F1", 100),
new Price("F2", 150),
new Price("O1", 250),
new Price("O2", 300));

public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices)

Map<String, Integer> bestPrice = new HashMap<String, Integer>();
for (PriceGroup priceGroup : priceGroups)
if (bestPrice.get(priceGroup.priceGroup) == null)
bestPrice.put(priceGroup.priceGroup, 10000000);


for (Price price : prices)
if (price.priceName.equals(priceGroup.priceName))
bestPrice.put(priceGroup.priceGroup, Math.min(price.price, bestPrice.get(priceGroup.priceGroup)));




return bestPrice;



For the given data, my function should return a map with:




F1 => 100

O1 => 250








java java-8 java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 7 at 15:54









Ruslan

4,2311028




4,2311028










asked Mar 7 at 14:06









ab11ab11

9,2073289175




9,2073289175







  • 2





    at first, please make your code compile. new PriceGroup("F1", 100) won't work.

    – Markus Mitterauer
    Mar 7 at 14:08











  • List Prices should not be populated with PriceGroup objects - please correct your typo.

    – PM 77-1
    Mar 7 at 14:10











  • Sorry, corrected.

    – ab11
    Mar 7 at 14:11











  • second, I think Map<String, Price> prices and Map<String, PriceGroup> priceGroups would suite your problem better, because you could access the elements by name, instead of iterating over them.

    – Markus Mitterauer
    Mar 7 at 14:12











  • possibly, I wrote this only to ask the question of what is the java1.8 way of joining two lists on an id, and finding some minimum value from another list based on that id.

    – ab11
    Mar 7 at 14:13












  • 2





    at first, please make your code compile. new PriceGroup("F1", 100) won't work.

    – Markus Mitterauer
    Mar 7 at 14:08











  • List Prices should not be populated with PriceGroup objects - please correct your typo.

    – PM 77-1
    Mar 7 at 14:10











  • Sorry, corrected.

    – ab11
    Mar 7 at 14:11











  • second, I think Map<String, Price> prices and Map<String, PriceGroup> priceGroups would suite your problem better, because you could access the elements by name, instead of iterating over them.

    – Markus Mitterauer
    Mar 7 at 14:12











  • possibly, I wrote this only to ask the question of what is the java1.8 way of joining two lists on an id, and finding some minimum value from another list based on that id.

    – ab11
    Mar 7 at 14:13







2




2





at first, please make your code compile. new PriceGroup("F1", 100) won't work.

– Markus Mitterauer
Mar 7 at 14:08





at first, please make your code compile. new PriceGroup("F1", 100) won't work.

– Markus Mitterauer
Mar 7 at 14:08













List Prices should not be populated with PriceGroup objects - please correct your typo.

– PM 77-1
Mar 7 at 14:10





List Prices should not be populated with PriceGroup objects - please correct your typo.

– PM 77-1
Mar 7 at 14:10













Sorry, corrected.

– ab11
Mar 7 at 14:11





Sorry, corrected.

– ab11
Mar 7 at 14:11













second, I think Map<String, Price> prices and Map<String, PriceGroup> priceGroups would suite your problem better, because you could access the elements by name, instead of iterating over them.

– Markus Mitterauer
Mar 7 at 14:12





second, I think Map<String, Price> prices and Map<String, PriceGroup> priceGroups would suite your problem better, because you could access the elements by name, instead of iterating over them.

– Markus Mitterauer
Mar 7 at 14:12













possibly, I wrote this only to ask the question of what is the java1.8 way of joining two lists on an id, and finding some minimum value from another list based on that id.

– ab11
Mar 7 at 14:13





possibly, I wrote this only to ask the question of what is the java1.8 way of joining two lists on an id, and finding some minimum value from another list based on that id.

– ab11
Mar 7 at 14:13












3 Answers
3






active

oldest

votes


















2














To get 2 lists joined you could consider to create dedicated object:



class Joined {
String priceGroup;
String priceName;
Integer price;
...


Then, using flatMap you can join priceGroups to prices on priceName field and group by priceGroup:



Map<String, Optional<Joined>> map = priceGroups.stream()
.flatMap(group -> prices.stream()
.filter(p -> p.getPriceName().equals(group.getPriceName()))
.map(p -> new Joined(group.getPriceGroup(), group.getPriceName(), p.getPrice())))
.collect(groupingBy(Joined::getPriceGroup, minBy(Comparator.comparing(Joined::getPrice))));


Now getting values from map you can print expected result:



for (Optional<Joined> value : map.values()) 
value.ifPresent(joined -> System.out.println(joined.getPriceName() + " " + joined.getPrice()));


// O1 250
// F1 100





share|improve this answer

























  • An associative class shouldn't really be required IMHO.

    – Naman
    Mar 7 at 16:13


















2














First: I think @Ruslan's answer is what you should use.



But you mentioned that the return has to be Map<String, Integer> and that the String should be the F1 instead of Friends. So I tried to get it all in one go and got this abomination of a function:



public static Map<String, Integer> getBestPricesV2(List<PriceGroup> priceGroups, List<Price> prices) 
final String unknownPriceName = "Unkown price name";

return prices.stream().collect(Collectors.groupingBy(
// map the price name the priceGroup name
price -> priceGroups.stream()
.filter(priceGroup -> priceGroup.getPriceName().equals(price.getPriceName()))
.findFirst()
.map(PriceGroup::getPriceGroup)
.orElse(unknownPriceName),
Collectors.minBy(Comparator.comparing(Price::getPrice))))
.entrySet()
.stream()
// extract the Optional<Price> to the price value
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().orElse(new Price(unknownPriceName, -1)).getPrice()));






share|improve this answer























  • On the filter line, I get no method found for price.getPriceName(). priceeGroup.getPriceName() works. Possibly this is the wrong syntax for the price variable? my idea does not seem to know that price is of type Price

    – ab11
    Mar 7 at 18:46











  • @ab11 hm, you could try to provide the type yourself by writing (Price price) -> ...

    – ifloop
    Mar 8 at 6:48


















2














You can simply avoid using a join class for this operation and perform it as :



public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices) 
// create a map of priceName to minimum price value using list of prices
Map<String, Integer> minPrice = prices.stream()
.collect(Collectors.groupingBy(Price::getPriceName,
Collectors.reducing(0, Price::getPrice,
BinaryOperator.minBy(Comparator.naturalOrder()))));

// use the map above to fill in the best prices map with values present or default
return priceGroups.stream()
.collect(Collectors.toMap(PriceGroup::getPriceGroup,
priceGroup ->
minPrice.getOrDefault(priceGroup.getPriceName(), 10000000)));






share|improve this answer























  • Assumption: Identity 0 while comparing considering the prices wouldn't be negative integers.

    – Naman
    Mar 7 at 16:16











  • Wouldn't an IllegalStateException be thrown due to duplicate keys?

    – Ruslan
    Mar 7 at 16:22











  • @Ruslan Well that's under another assumption that the priceGroup are unique, or else the value mapped would require a mergeFunction, in the OP's case a default selecting any value (a,b) -> a

    – Naman
    Mar 7 at 16:27











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55045724%2fhow-2-lists-can-be-joined-using-streams-and-1-8-functions%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














To get 2 lists joined you could consider to create dedicated object:



class Joined {
String priceGroup;
String priceName;
Integer price;
...


Then, using flatMap you can join priceGroups to prices on priceName field and group by priceGroup:



Map<String, Optional<Joined>> map = priceGroups.stream()
.flatMap(group -> prices.stream()
.filter(p -> p.getPriceName().equals(group.getPriceName()))
.map(p -> new Joined(group.getPriceGroup(), group.getPriceName(), p.getPrice())))
.collect(groupingBy(Joined::getPriceGroup, minBy(Comparator.comparing(Joined::getPrice))));


Now getting values from map you can print expected result:



for (Optional<Joined> value : map.values()) 
value.ifPresent(joined -> System.out.println(joined.getPriceName() + " " + joined.getPrice()));


// O1 250
// F1 100





share|improve this answer

























  • An associative class shouldn't really be required IMHO.

    – Naman
    Mar 7 at 16:13















2














To get 2 lists joined you could consider to create dedicated object:



class Joined {
String priceGroup;
String priceName;
Integer price;
...


Then, using flatMap you can join priceGroups to prices on priceName field and group by priceGroup:



Map<String, Optional<Joined>> map = priceGroups.stream()
.flatMap(group -> prices.stream()
.filter(p -> p.getPriceName().equals(group.getPriceName()))
.map(p -> new Joined(group.getPriceGroup(), group.getPriceName(), p.getPrice())))
.collect(groupingBy(Joined::getPriceGroup, minBy(Comparator.comparing(Joined::getPrice))));


Now getting values from map you can print expected result:



for (Optional<Joined> value : map.values()) 
value.ifPresent(joined -> System.out.println(joined.getPriceName() + " " + joined.getPrice()));


// O1 250
// F1 100





share|improve this answer

























  • An associative class shouldn't really be required IMHO.

    – Naman
    Mar 7 at 16:13













2












2








2







To get 2 lists joined you could consider to create dedicated object:



class Joined {
String priceGroup;
String priceName;
Integer price;
...


Then, using flatMap you can join priceGroups to prices on priceName field and group by priceGroup:



Map<String, Optional<Joined>> map = priceGroups.stream()
.flatMap(group -> prices.stream()
.filter(p -> p.getPriceName().equals(group.getPriceName()))
.map(p -> new Joined(group.getPriceGroup(), group.getPriceName(), p.getPrice())))
.collect(groupingBy(Joined::getPriceGroup, minBy(Comparator.comparing(Joined::getPrice))));


Now getting values from map you can print expected result:



for (Optional<Joined> value : map.values()) 
value.ifPresent(joined -> System.out.println(joined.getPriceName() + " " + joined.getPrice()));


// O1 250
// F1 100





share|improve this answer















To get 2 lists joined you could consider to create dedicated object:



class Joined {
String priceGroup;
String priceName;
Integer price;
...


Then, using flatMap you can join priceGroups to prices on priceName field and group by priceGroup:



Map<String, Optional<Joined>> map = priceGroups.stream()
.flatMap(group -> prices.stream()
.filter(p -> p.getPriceName().equals(group.getPriceName()))
.map(p -> new Joined(group.getPriceGroup(), group.getPriceName(), p.getPrice())))
.collect(groupingBy(Joined::getPriceGroup, minBy(Comparator.comparing(Joined::getPrice))));


Now getting values from map you can print expected result:



for (Optional<Joined> value : map.values()) 
value.ifPresent(joined -> System.out.println(joined.getPriceName() + " " + joined.getPrice()));


// O1 250
// F1 100






share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 7 at 17:11

























answered Mar 7 at 15:05









RuslanRuslan

4,2311028




4,2311028












  • An associative class shouldn't really be required IMHO.

    – Naman
    Mar 7 at 16:13

















  • An associative class shouldn't really be required IMHO.

    – Naman
    Mar 7 at 16:13
















An associative class shouldn't really be required IMHO.

– Naman
Mar 7 at 16:13





An associative class shouldn't really be required IMHO.

– Naman
Mar 7 at 16:13













2














First: I think @Ruslan's answer is what you should use.



But you mentioned that the return has to be Map<String, Integer> and that the String should be the F1 instead of Friends. So I tried to get it all in one go and got this abomination of a function:



public static Map<String, Integer> getBestPricesV2(List<PriceGroup> priceGroups, List<Price> prices) 
final String unknownPriceName = "Unkown price name";

return prices.stream().collect(Collectors.groupingBy(
// map the price name the priceGroup name
price -> priceGroups.stream()
.filter(priceGroup -> priceGroup.getPriceName().equals(price.getPriceName()))
.findFirst()
.map(PriceGroup::getPriceGroup)
.orElse(unknownPriceName),
Collectors.minBy(Comparator.comparing(Price::getPrice))))
.entrySet()
.stream()
// extract the Optional<Price> to the price value
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().orElse(new Price(unknownPriceName, -1)).getPrice()));






share|improve this answer























  • On the filter line, I get no method found for price.getPriceName(). priceeGroup.getPriceName() works. Possibly this is the wrong syntax for the price variable? my idea does not seem to know that price is of type Price

    – ab11
    Mar 7 at 18:46











  • @ab11 hm, you could try to provide the type yourself by writing (Price price) -> ...

    – ifloop
    Mar 8 at 6:48















2














First: I think @Ruslan's answer is what you should use.



But you mentioned that the return has to be Map<String, Integer> and that the String should be the F1 instead of Friends. So I tried to get it all in one go and got this abomination of a function:



public static Map<String, Integer> getBestPricesV2(List<PriceGroup> priceGroups, List<Price> prices) 
final String unknownPriceName = "Unkown price name";

return prices.stream().collect(Collectors.groupingBy(
// map the price name the priceGroup name
price -> priceGroups.stream()
.filter(priceGroup -> priceGroup.getPriceName().equals(price.getPriceName()))
.findFirst()
.map(PriceGroup::getPriceGroup)
.orElse(unknownPriceName),
Collectors.minBy(Comparator.comparing(Price::getPrice))))
.entrySet()
.stream()
// extract the Optional<Price> to the price value
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().orElse(new Price(unknownPriceName, -1)).getPrice()));






share|improve this answer























  • On the filter line, I get no method found for price.getPriceName(). priceeGroup.getPriceName() works. Possibly this is the wrong syntax for the price variable? my idea does not seem to know that price is of type Price

    – ab11
    Mar 7 at 18:46











  • @ab11 hm, you could try to provide the type yourself by writing (Price price) -> ...

    – ifloop
    Mar 8 at 6:48













2












2








2







First: I think @Ruslan's answer is what you should use.



But you mentioned that the return has to be Map<String, Integer> and that the String should be the F1 instead of Friends. So I tried to get it all in one go and got this abomination of a function:



public static Map<String, Integer> getBestPricesV2(List<PriceGroup> priceGroups, List<Price> prices) 
final String unknownPriceName = "Unkown price name";

return prices.stream().collect(Collectors.groupingBy(
// map the price name the priceGroup name
price -> priceGroups.stream()
.filter(priceGroup -> priceGroup.getPriceName().equals(price.getPriceName()))
.findFirst()
.map(PriceGroup::getPriceGroup)
.orElse(unknownPriceName),
Collectors.minBy(Comparator.comparing(Price::getPrice))))
.entrySet()
.stream()
// extract the Optional<Price> to the price value
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().orElse(new Price(unknownPriceName, -1)).getPrice()));






share|improve this answer













First: I think @Ruslan's answer is what you should use.



But you mentioned that the return has to be Map<String, Integer> and that the String should be the F1 instead of Friends. So I tried to get it all in one go and got this abomination of a function:



public static Map<String, Integer> getBestPricesV2(List<PriceGroup> priceGroups, List<Price> prices) 
final String unknownPriceName = "Unkown price name";

return prices.stream().collect(Collectors.groupingBy(
// map the price name the priceGroup name
price -> priceGroups.stream()
.filter(priceGroup -> priceGroup.getPriceName().equals(price.getPriceName()))
.findFirst()
.map(PriceGroup::getPriceGroup)
.orElse(unknownPriceName),
Collectors.minBy(Comparator.comparing(Price::getPrice))))
.entrySet()
.stream()
// extract the Optional<Price> to the price value
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().orElse(new Price(unknownPriceName, -1)).getPrice()));







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 7 at 15:06









ifloopifloop

5,26111835




5,26111835












  • On the filter line, I get no method found for price.getPriceName(). priceeGroup.getPriceName() works. Possibly this is the wrong syntax for the price variable? my idea does not seem to know that price is of type Price

    – ab11
    Mar 7 at 18:46











  • @ab11 hm, you could try to provide the type yourself by writing (Price price) -> ...

    – ifloop
    Mar 8 at 6:48

















  • On the filter line, I get no method found for price.getPriceName(). priceeGroup.getPriceName() works. Possibly this is the wrong syntax for the price variable? my idea does not seem to know that price is of type Price

    – ab11
    Mar 7 at 18:46











  • @ab11 hm, you could try to provide the type yourself by writing (Price price) -> ...

    – ifloop
    Mar 8 at 6:48
















On the filter line, I get no method found for price.getPriceName(). priceeGroup.getPriceName() works. Possibly this is the wrong syntax for the price variable? my idea does not seem to know that price is of type Price

– ab11
Mar 7 at 18:46





On the filter line, I get no method found for price.getPriceName(). priceeGroup.getPriceName() works. Possibly this is the wrong syntax for the price variable? my idea does not seem to know that price is of type Price

– ab11
Mar 7 at 18:46













@ab11 hm, you could try to provide the type yourself by writing (Price price) -> ...

– ifloop
Mar 8 at 6:48





@ab11 hm, you could try to provide the type yourself by writing (Price price) -> ...

– ifloop
Mar 8 at 6:48











2














You can simply avoid using a join class for this operation and perform it as :



public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices) 
// create a map of priceName to minimum price value using list of prices
Map<String, Integer> minPrice = prices.stream()
.collect(Collectors.groupingBy(Price::getPriceName,
Collectors.reducing(0, Price::getPrice,
BinaryOperator.minBy(Comparator.naturalOrder()))));

// use the map above to fill in the best prices map with values present or default
return priceGroups.stream()
.collect(Collectors.toMap(PriceGroup::getPriceGroup,
priceGroup ->
minPrice.getOrDefault(priceGroup.getPriceName(), 10000000)));






share|improve this answer























  • Assumption: Identity 0 while comparing considering the prices wouldn't be negative integers.

    – Naman
    Mar 7 at 16:16











  • Wouldn't an IllegalStateException be thrown due to duplicate keys?

    – Ruslan
    Mar 7 at 16:22











  • @Ruslan Well that's under another assumption that the priceGroup are unique, or else the value mapped would require a mergeFunction, in the OP's case a default selecting any value (a,b) -> a

    – Naman
    Mar 7 at 16:27















2














You can simply avoid using a join class for this operation and perform it as :



public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices) 
// create a map of priceName to minimum price value using list of prices
Map<String, Integer> minPrice = prices.stream()
.collect(Collectors.groupingBy(Price::getPriceName,
Collectors.reducing(0, Price::getPrice,
BinaryOperator.minBy(Comparator.naturalOrder()))));

// use the map above to fill in the best prices map with values present or default
return priceGroups.stream()
.collect(Collectors.toMap(PriceGroup::getPriceGroup,
priceGroup ->
minPrice.getOrDefault(priceGroup.getPriceName(), 10000000)));






share|improve this answer























  • Assumption: Identity 0 while comparing considering the prices wouldn't be negative integers.

    – Naman
    Mar 7 at 16:16











  • Wouldn't an IllegalStateException be thrown due to duplicate keys?

    – Ruslan
    Mar 7 at 16:22











  • @Ruslan Well that's under another assumption that the priceGroup are unique, or else the value mapped would require a mergeFunction, in the OP's case a default selecting any value (a,b) -> a

    – Naman
    Mar 7 at 16:27













2












2








2







You can simply avoid using a join class for this operation and perform it as :



public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices) 
// create a map of priceName to minimum price value using list of prices
Map<String, Integer> minPrice = prices.stream()
.collect(Collectors.groupingBy(Price::getPriceName,
Collectors.reducing(0, Price::getPrice,
BinaryOperator.minBy(Comparator.naturalOrder()))));

// use the map above to fill in the best prices map with values present or default
return priceGroups.stream()
.collect(Collectors.toMap(PriceGroup::getPriceGroup,
priceGroup ->
minPrice.getOrDefault(priceGroup.getPriceName(), 10000000)));






share|improve this answer













You can simply avoid using a join class for this operation and perform it as :



public Map<String, Integer> getBestPrices(List<PriceGroup> priceGroups, List<Price> prices) 
// create a map of priceName to minimum price value using list of prices
Map<String, Integer> minPrice = prices.stream()
.collect(Collectors.groupingBy(Price::getPriceName,
Collectors.reducing(0, Price::getPrice,
BinaryOperator.minBy(Comparator.naturalOrder()))));

// use the map above to fill in the best prices map with values present or default
return priceGroups.stream()
.collect(Collectors.toMap(PriceGroup::getPriceGroup,
priceGroup ->
minPrice.getOrDefault(priceGroup.getPriceName(), 10000000)));







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 7 at 16:11









NamanNaman

45.1k11102204




45.1k11102204












  • Assumption: Identity 0 while comparing considering the prices wouldn't be negative integers.

    – Naman
    Mar 7 at 16:16











  • Wouldn't an IllegalStateException be thrown due to duplicate keys?

    – Ruslan
    Mar 7 at 16:22











  • @Ruslan Well that's under another assumption that the priceGroup are unique, or else the value mapped would require a mergeFunction, in the OP's case a default selecting any value (a,b) -> a

    – Naman
    Mar 7 at 16:27

















  • Assumption: Identity 0 while comparing considering the prices wouldn't be negative integers.

    – Naman
    Mar 7 at 16:16











  • Wouldn't an IllegalStateException be thrown due to duplicate keys?

    – Ruslan
    Mar 7 at 16:22











  • @Ruslan Well that's under another assumption that the priceGroup are unique, or else the value mapped would require a mergeFunction, in the OP's case a default selecting any value (a,b) -> a

    – Naman
    Mar 7 at 16:27
















Assumption: Identity 0 while comparing considering the prices wouldn't be negative integers.

– Naman
Mar 7 at 16:16





Assumption: Identity 0 while comparing considering the prices wouldn't be negative integers.

– Naman
Mar 7 at 16:16













Wouldn't an IllegalStateException be thrown due to duplicate keys?

– Ruslan
Mar 7 at 16:22





Wouldn't an IllegalStateException be thrown due to duplicate keys?

– Ruslan
Mar 7 at 16:22













@Ruslan Well that's under another assumption that the priceGroup are unique, or else the value mapped would require a mergeFunction, in the OP's case a default selecting any value (a,b) -> a

– Naman
Mar 7 at 16:27





@Ruslan Well that's under another assumption that the priceGroup are unique, or else the value mapped would require a mergeFunction, in the OP's case a default selecting any value (a,b) -> a

– Naman
Mar 7 at 16:27

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55045724%2fhow-2-lists-can-be-joined-using-streams-and-1-8-functions%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

1928 у кіно

Захаров Федір Захарович

Ель Греко