java 返回从数组列表派生的哈希Map

2jcobegt  于 2023-03-11  发布在  Java
关注(0)|答案(1)|浏览(98)

我正在尝试返回一个HashMap,其中包含公交车号码和车站。
我已经创建了一个方法,通过将其中一个stop传递给HashSet来返回它。
我觉得一切都可以走到一起,但我一直在兜圈子。

public class BusRoutes
{

    public HashMap<Integer,ArrayList<String>> routes;

    public void populateRoutes()
    {
        ArrayList<String> stops = new ArrayList<>();
        stops.add("High Street");
        stops.add("Acacia Avenue");
        stops.add("Brown Street");
        stops.add("Broadway");
        stops.add("Station");
        routes.put(32, stops);

        ArrayList<String> stops1 = new ArrayList<>();
        stops1.add("High Street");
        stops1.add("Hospital");
        stops1.add("Brown Street");
        stops1.add("School");
        stops1.add("Station");
        routes.put(13, stops1);
    }

    public BusRoutes() {
        routes = new HashMap<>();
        reader = new InputReader();
        populateRoutes();        
    }
    public void printRoute(int busNum) {
        System.out.println("Bus number " + busNum + " route:");

        for (int i = 0; i < routes.get(busNum).size(); i++) {
            System.out.println(routes.get(busNum).get(i));
        }        

    }

    public void printAllRoutes() {
        for (int i = 0; i < routes.size(); i++) {
            System.out.println(routes.get(i));
        }       
    }

    public HashSet<Integer> getBusesStoppingHere(String aStop) {    
        HashSet<Integer> busNumbers = new HashSet<>();

        for (Integer key : routes.keySet()) {
            if (routes.get(key).contains(aStop)) {
                busNumbers.add(key);
            }
        }

        return busNumbers;
    }

    public HashMap<String, HashSet<Integer>> getStopsAndBusNumbers() {
        HashMap<String, HashSet<Integer>> map = new HashMap<String, HashSet<Integer>>();
        
        // This is where I am stuck

        return map;
    }
}
q8l4jmvw

q8l4jmvw1#

我想返回一个从routes派生的Map,其中routesMap中包含的每个站点都是一个键,每个值都是一组在其路线上有该站点的公交车号码。
我相信这会奏效的做你想做的。

  • 首先分配一条记录来保存一个站点和公交车号码。也可以使用Map.entry()方法,但是该记录不需要任何开销,并且为参数提供了有意义的名称。
  • 然后流式传输现有Map的entrySet()
  • 然后使用flatMap(),对entrySet's站点进行流处理,每个站点和相关的公共汽车将Map到记录。
  • 现在只需要将每个站点分组为一组公共汽车。
  • Collectors.groupingBy还将使用另一个收集器(在本例中为Collectors.mapping)从Pair示例中提取总线号,然后放入一个集合中。
record Pair(String getStop, Integer getBus) {}

public  Map<String, Set<Integer>> getStopsAndBusNumbers(Map<Integer, List<String>> map) {
  return map.entrySet()
      .stream()
      .flatMap(e->e.getValue().stream().map(stop->new Pair(stop, e.getKey())))
      .collect(Collectors.groupingBy(Pair::getStop,
           Collectors.mapping(Pair::getBus, Collectors.toSet())));
}

当使用路线图调用时,将显示以下结果。

Station=[32, 13]
School=[13]
Brown Street=[32, 13]
High Street=[32, 13]
Acacia Avenue=[32]
Broadway=[32]
Hospital=[13]

为了顺利地工作,你应该将你的类型改变为它们的定义接口。所以HashMap<String, ArrayList<Integer>>应该声明为Map<String, List<Integer>>,等等。这不仅仅是为了这个练习,而是Java中的标准实践。你总是可以将object传递或赋值给它的定义interface,但不能匡威(不强制转换),因为该接口可能存在不同的实现。
下面是一个更迫切的解决方案,可能是Java8之前的方法。结果是相同的,尽管涉及到Map和集合时,内容的顺序可能会改变。它使用嵌套循环首先迭代键(总线),然后是值(stops)。问题的核心是检查站点是否存在。如果不存在,则使用新的HashSet添加它。然后简单地继续执行条件并将公交车号码添加到集合中。

public Map<String, Set<Integer>> getStopsAndBusNumbers2(
        Map<Integer, List<String>> map) {
    Map<String, Set<Integer>> result = new HashMap<>();
    for (Entry<Integer, List<String>> e : map.entrySet()) {
        for (String stop : e.getValue()) {
            if (!result.containsKey(stop)) {
                result.put(stop, new HashSet<Integer>());
            }
            result.get(stop).add(e.getKey()); // add bus for stop
        }
    }
    return result;
}

相关问题