I have a List counties
which contains unique county names only, and a List txcArray
which contains a city name, county name and population for that city.
I need to get the largest city name of each county from txcArray
using only Java 8 with lambda expressions and Stream
s.
Here is the code I have so far:
List<String> largest_city_name =
counties.stream()
.map(a -> txcArray.stream()
.filter(b -> b.getCounty().equals(a))
.mapToInt(c -> c.getPopulation())
.max())
.collect( Collectors.toList());
I am trying to add another .map statement after .max()
to get the name of the City
with the largest population but my new lambda expression does not exists from the stream of txcArray it only recognizes it as an int
type and a texasCitiesClass type. Here is what I am trying to do.
List<String> largest_city_name =
counties.stream()
.map(a -> txcArray.stream()
.filter( b -> b.getCounty().equals(a))
.mapToInt(c->c.getPopulation())
.max()
.map(d->d.getName()))
.collect( Collectors.toList());
Can someone tell me what I am doing wrong?
You don't need the counties
list altogether. Just stream txcArray
and group by county:
Collection<String> largestCityNames = txcArray.stream()
.collect(Collectors.groupingBy(
City::getCounty,
Collectors.collectingAndThen(
Collectors.maxBy(City::getPopulation),
o -> o.get().getName())))
.values();
Well, once to map
the Stream
of cities into an IntStream
, there's no way for you to recover the name of the city corresponding with the int
value.
Use Stream
's max
instead of converting to IntStream
:
List<String> largest_city_name =
counties.stream()
.map(a -> txcArray.stream()
.filter(b -> b.getCounty().equals(a))
.max(Comparator.comparingInt(City::getPopulation))
.get())
.map(City::getName)
.collect(Collectors.toList());
This way the map
operation maps each county to its City
with the highest population. Note that max
returns an Optional<City>
, so it the Optional
is empty (i.e. some county has no cities), get()
will throw an exception.
To avoid that issue, you can write:
List<String> largest_city_name =
counties.stream()
.map(a -> txcArray.stream()
.filter(b -> b.getCounty().equals(a))
.max(Comparator.comparingInt(City::getPopulation))
.map(City::getName)
.orElse(""))
.collect(Collectors.toList());
This will map a county having no cities into an empty String
.
This code assumes txcArray
is a List<City>
, where City
is:
class City { public String getName () {return nam;} public int getPopulation() {return pop;} public String getCounty() {return cnt;} String nam; int pop; String cnt; public City(String nam,int pop,String cnt) { this.nam = nam; this.pop = pop; this.cnt = cnt; } }
and counties
is a List<String>
. If my assumptions are not accurate, you'll have to make some adjustments.
Now, testing the code with the following List
s:
List<String> counties=new ArrayList<> ();
counties.add ("First");
counties.add ("Second");
counties.add ("Third");
counties.add ("Fourth");
List<City> txcArray = new ArrayList<> ();
txcArray.add (new City("One",15000,"First"));
txcArray.add (new City("Two",12000,"First"));
txcArray.add (new City("Three",150000,"Second"));
txcArray.add (new City("Four",14000,"Second"));
txcArray.add (new City("Five",615000,"Third"));
txcArray.add (new City("Six",25000,"Third"));
produces this output List
:
[One, Three, Five, ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With