How to filter HashMap using stream in proper way?
I have a HashMap
. I would like to filter this HashMap
using three separate methods. In my HashMap
I have three positions: from, by, to.
The first method should filter my HashMap
using for example: from. If I choose a "city1"
the method should display only all connections where from ='city1'
The second method should filter my HashMap
using for example: by. This method and stream should displays all connections where by ="city2"
or for example empty string = ""
in that case
The third method should filter my HashMap
using for example: to ="city3"
If I choose a "city3"
the method should display only all connections where to ='city3'
The fourth method display all HashMap
– it works fine.
public static Map<Integer, City> getAllCitiesMap() { Map<Integer, City> allCitiesMap = new HashMap<Integer, City>(); allCitiesMap.put(0,new City("city1","", "city2")); allCitiesMap.put(1,new City("city1","city2", "city4")); allCitiesMap.put(2,new City("city1", "","city5")); allCitiesMap.put(3,new City("city1", "city2","city7")); allCitiesMap.put(4,new City("city2","", "city1")); allCitiesMap.put(5,new City("city2", "city1","city8")); allCitiesMap.put(6,new City("city2", "","city6")); allCitiesMap.put(7,new City("city2", "","city5")); allCitiesMap.put(8,new City("city2", "","city4")); allCitiesMap.put(9,new City("city2", "","city7")); return allCitiesMap; } public class City { private static String from; private static String by; private static String to; public City(String from, String by, String to) { this.from = from; this.by = by; this.to = to; } public static String getFrom() { return from; } public static String getBy() { return by; } public static String getTo() { return to; }
I did four methods but these methods don’t display and don’t filter what I would like to see. Only the fourth method works fine. How to do it, improve a code below?
1.
public static void findAllConnectionFromOneCity(){ AllCities.getAllCitiesMap().entrySet().stream() .filter(c -> City.getFrom().equals("city1")) .forEach(System.out::println); }
public static void findAllConnectionToOneCity(){ AllCities.getAllCitiesMap().entrySet().stream() .filter(c -> City.getBy().equals("city1")) .forEach(System.out::println); }
-
public static void filterCities(Map<Integer, String> allCitiesMap){ Map<Integer, String> filteredCitiesMap = allCitiesMap.entrySet() .stream() .filter(s -> City.getTo().equals("city1")) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); }
public static void findAllCities(){ AllCities.getAllCitiesMap().entrySet().stream() .forEach(System.out::println); }
First of all, do not define setters
and getters
as static. They are the means to access object fields and shouldn’t be static.
More on it here ..
https://docs.oracle.com/javaee/6/tutorial/doc/gjbbp.html https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
Since you have a Map
where you have kept all your City
objects, you should be creating a stream on the values of the map
rather than the keys:
public static void findAllConnectionFromOneCity(){ AllCities.getAllCitiesMap().entrySet().stream() .filter(c -> City.getFrom().equals("city1")) .forEach(System.out::println); }
If there’s no specific reason to keep the City
objects in Map
, you should change the data structure to a List
and you can then use something like this to access the information
public static void findAllConnectionFromOneCityList() { AllCities.getAllCities().stream().filter(c -> c.getFrom().equals("city1")) .forEach(System.out::println); }
You need to work on your design. You are making use of a Map
without harnessing it’s key-value functionality. In such cases, you can think of choosing List
as suggested by fellow community members. However I can point out what might be going wrong with your existing code.
It can be observed that filter
method is called directly on the entrySet()
and you are trying to filter cities. But actually at this point filter
method will have Stream<Map.Entry<Integer, City>>
and NOT Stream<City>
itself. Hence, you should convert the stream to Stream<City>
first before filtering.
allCitiesMap.entrySet().stream() .map(entry -> entry.getValue()) .filter(city -> city.getFrom().equals("city1")) .forEach(System.out::println);
Or
You can also make use of Map.values()
as:
allCitiesMap.values().stream() .filter(city -> city.getFrom().equals("city1")) .forEach(System.out::println);