Как правильно фильтровать HashMap с помощью потока? - PullRequest
0 голосов
/ 13 июля 2020

У меня HashMap. Я хотел бы отфильтровать этот HashMap тремя разными способами. В моем HashMap у меня есть три позиции: от, по, до.

Первый метод должен фильтровать мой HashMap, например, используя: from. Если я выберу "city1", метод должен отображать только все подключения, где from ='city1'

Второй метод должен отфильтровать мой HashMap, используя, например: by. Этот метод и поток должны отображать все соединения, где by ="city2" или, например, пустой string = "", в этом случае

Третий метод должен фильтровать мои HashMap, используя, например: to ="city3" Если я выберу "city3" метод должен отображать только все соединения, где to ='city3'

Четвертый метод отображает все HashMap - он работает нормально.

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;
    }

Я использовал четыре метода, но эти методы не отображать и не фильтровать то, что я хотел бы видеть. Только четвертый способ работает нормально. Как это сделать, улучшите код ниже?

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);
    }

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Вам нужно поработать над своим дизайном. Вы используете Map, не используя его функциональные возможности "ключ-значение". В таких случаях вы можете подумать о выборе List, как предложено другими членами сообщества. Однако я могу указать, что может быть не так с вашим существующим кодом.

Можно заметить, что метод filter вызывается непосредственно на entrySet(), и вы пытаетесь отфильтровать города. Но на самом деле в этот момент метод filter будет иметь Stream<Map.Entry<Integer, City>>, а НЕ сам Stream<City>. Следовательно, вы должны сначала преобразовать поток в Stream<City> перед фильтрацией.

allCitiesMap.entrySet().stream()
.map(entry -> entry.getValue())
.filter(city -> city.getFrom().equals("city1"))
.forEach(System.out::println);

Или

Вы также можете использовать Map.values() как:

allCitiesMap.values().stream()
    .filter(city -> city.getFrom().equals("city1"))
    .forEach(System.out::println);
1 голос
/ 13 июля 2020

Прежде всего, не определяйте setters и getters как stati c. Они являются средствами доступа к полям объекта и не должны быть stati c.

Подробнее об этом здесь ..
https://docs.oracle.com/javaee/6/tutorial/doc/gjbbp.html https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

Поскольку у вас есть Map, где вы храните все свои City объекты , вы должны создавать поток по значениям map, а не по ключам:

public static void findAllConnectionFromOneCity(){    
    AllCities.getAllCitiesMap().entrySet().stream()
            .filter(c -> City.getFrom().equals("city1"))
            .forEach(System.out::println);
}

Если нет определенной c причины хранить объекты City в Map, вы следует изменить структуру данных на List, и затем вы можете использовать что-то вроде этого для доступа к информации

public static void findAllConnectionFromOneCityList() {
    AllCities.getAllCities().stream().filter(c -> c.getFrom().equals("city1"))
            .forEach(System.out::println);
}
...