有没有更有效的方法使用ArrayList中的计数器来创建HashMap?

时间:2018-05-28 12:18:20

标签: java sorting arraylist hashmap counter

我有一种方法可以让我通过获取HashMap对象,然后将邻域名称与ArrayList中的任意键进行比较,从AirbnbListing创建HashMap。如果它还没有在hashmap中,我将它添加一个从1开始的计数器,如果它已经存在,我会增加计数器。

这里有一个更有效的方法是我的代码:

    public HashMap<String, Integer> sortHousesInNbrhood(ArrayList<AirbnbListing> priceRangeListing) {
    HashMap<String, Integer> housesInNbrhood = new HashMap<>();
    for (AirbnbListing listing : priceRangeListing) {
        if (housesInNbrhood.isEmpty()) {
            housesInNbrhood.put(listing.getNeighbourhood(), 1); 
        } else if (housesInNbrhood.containsKey(listing.getNeighbourhood())) {
            housesInNbrhood.replace(listing.getNeighbourhood(), housesInNbrhood.get(listing.getNeighbourhood()) + 1);
        } else {
            housesInNbrhood.put(listing.getNeighbourhood(),1); 
        }
    }

    return housesInNbrhood;
}

3 个答案:

答案 0 :(得分:8)

使用groupingBy收集器和counting作为下游收集器:

priceRangeListing.stream()
                 .collect(groupingBy(AirbnbListing::getNeighbourhood, counting()));

注意,上面会产生一个Map<String, Long>,但是如果你真的想要Map<String, Integer>,那么使用summingInt收集器作为下游:

priceRangeListing.stream()
       .collect(groupingBy(AirbnbListing::getNeighbourhood, summingInt(e -> 1)));

答案 1 :(得分:1)

public HashMap<String, Integer> sortHousesInNbrhood(ArrayList<AirbnbListing> priceRangeListing) {
    HashMap<String, Integer> housesInNbrhood = new HashMap<>();
    for (AirbnbListing listing : priceRangeListing) {
         housesInNbrhood.compute(listing.getNeighbourhood(), (k, v) -> (v == null) ? 1 : v + 1);
    }

    return housesInNbrhood;
}

答案 2 :(得分:0)

Multiset是专门用于跟踪对象在集合中出现的次数的数据结构。它们非常适合您的问题!

它们在Java标准库中不可用,但它们位于Guava库中。

我建议您使用HashMap替换Multiset作为方法的返回值。在这种情况下,读者将更清楚它包含的内容。

使用该解决方案,代码如下所示:

public Multiset<String> sortHousesInNbrhood(List<AirbnbListing> priceRangeListing) {
    Multiset<String> housesInNbrhood = TreeMultiset.create();
    // Multimap automatically counts the number of times an object have been added
    priceRangeListing.forEach(list -> housesInNbrhood.add(list.getNeighbourhood()));
    return housesInNbrhood;
}

// Use the multiset like this:
public void useMultiset(List<AirbnbListing> priceRangeListing) {
    Multiset<String> s = sortHousesInNbrhood(priceRangeListing);
    System.out.println("Houses in Bagdad:" + s.count("Bagdad"));

    System.out.println("All counts: ");
    for (Entry<String> e : s.entrySet()) {
        System.out.println(e.getElement() + ": " + e.getCount());
    }
}

如果您必须返回HashMap,那么您可以像Multiset那样构建它:

public Map<String, Integer> sortHousesInNbrhood_2(List<AirbnbListing> priceRangeListing) {
    Multiset<String> housesInNbrhood = TreeMultiset.create();
    priceRangeListing.forEach(list -> housesInNbrhood.add(list.getNeighbourhood()));
    return housesInNbrhood.entrySet().stream().collect(toMap(Entry::getElement, Entry::getCount));
}

Multisets和multimaps是我最喜欢的数据结构。太方便了!