亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 Stream 改進此 List 迭代?

如何使用 Stream 改進此 List 迭代?

斯蒂芬大帝 2022-07-27 21:37:17
我正在嘗試計算在對象列表中的字段中看到 Int 的次數。這是我的代碼TreeMap<Integer, Double> ratings = new TreeMap();ArrayList<Establishment> establishments = new ArrayList<>();double one = 0;double two = 0;double three = 0;double five = 0;for (Establishment e : establishments) {    if (e.getRating() == 1) {        one++;    }    if (e.getRating() == 2) {        two++;    }    if (e.getRating() == 3) {        three++;    }    if (e.getRating() == 5) {        five++;    }}    ratings.put(1, (one / establishments.size()) * 100);    ratings.put(2, (two / establishments.size()) * 100);    ratings.put(3, (three / establishments.size()) * 100);    ratings.put(5, (five / establishments.size()) * 100);但這并不理想,如果添加更多評分(例如 20+),那么您將創建一堆雙打,并且不可維護。我知道如果我有一個整數列表,我可以用 Stream 做一些事情,比如說listOfInts.stream().filter(i -> i == 3).count()然而,這是一個對象列表,其中包含一個 int,我需要計算該對象列表中的評級數 == X。所以我需要的偽代碼:建立emnts.getAllRatings().stream().filter(ratings -> rating == 3).count()** 對每個評級類型重復 1 - 5** 沒有 getAllRatings - 我想這就是我要解決的問題)
查看完整描述

5 回答

?
開滿天機

TA貢獻1786條經驗 獲得超13個贊

在循環中,您可以對值求和:


for (Establishment e : establishments) {

    // Get old value OR set to "0"

    Double rating = ratings.getOrDefault(e.getRating(), 0);

    // increase rating (counter)

    ratings.put(e.getRating(), rating + 1);

}

最后計算平均值:


// Calculate part of equation which is not changing in loop

int size = establishments.size() * 100;


for (Map.Entry<Integer, Double> entry : ratings.entrySet()) {

    // Calculate average

    Double average = entry.getValue() / size;

    // Add it to the map

    ratings.put(entry.getKey(), average);

}


查看完整回答
反對 回復 2022-07-27
?
回首憶惘然

TA貢獻1847條經驗 獲得超11個贊

你可以做:


Map<Integer, Double> ratings = new TreeMap<>();

List<Establishment> establishments = new ArrayList<>();

establishments.stream() 

              .collect(Collectors.groupingBy(Establishment::getRating, Collectors.counting()))

              .forEach((k, v) -> ratings.put(k, (double)v/establishments.size() * 100));

哪個將與 一起使用Collectors::groupingBy,Collectors::counting這將創建一個Map由評分計數組成的,然后用于forEach將它們添加到TreeMap


或者,正如 VGR 所建議的,更優雅地使用Collectors::collectingAndThen:


Map<Integer, Double> ratings =

establishments.stream()

              .collect(

                       Collectors.groupingBy(Establishment::getRating, 

                       Collectors.collectingAndThen(Collectors.counting(), c -> c * 100.0 / establishments.size())

               ));

這將直接創建,Map而無需創建 a Map,再次流過它,然后再次收集到Mapa


查看完整回答
反對 回復 2022-07-27
?
尚方寶劍之說

TA貢獻1788條經驗 獲得超4個贊

或多或少只使用流:

List<Establishment> establishments = new ArrayList<>();Map<Integer, Double> ratings = establishments.stream()
        .collect(Collectors.groupingBy(Establishment::getRating, Collectors.counting()))
        .entrySet()
        .stream()
        .collect(Collectors.toMap(e -> e.getKey(), 
                                  e -> 100.0 * (e.getValue() / establishments.size())));



查看完整回答
反對 回復 2022-07-27
?
白衣染霜花

TA貢獻1796條經驗 獲得超10個贊

以下是如何使用流實現 getAllRatings 以獲取評級列表

List<Integer> attributes = establishments.stream().map(es -> es.getRating()).collect(Collectors.toList());

因此,要獲得特定評級的評級計數,您可以使用

establishments.stream().map(es -> es.getRating()).collect(Collectors.toList()).stream().filter(ratings -> ratings == 3).count()

如果您想獲取所有評分的評分計數/百分比,請使用@Marek 答案中的代碼


查看完整回答
反對 回復 2022-07-27
?
慕碼人8056858

TA貢獻1803條經驗 獲得超6個贊

為了讓TreeMap<Integer, Double> ratings您可以將流 api 與groupingBysummingDouble作為下游一起使用:

TreeMap<Integer, Double> ratings = establishments.stream()
        .collect(Collectors.groupingBy(Establishment::getRating, TreeMap::new,
                Collectors.summingDouble(v -> ((1.0 / establishments.size())* 100))));

并計算次數:

long count = establishments.stream()
        .filter(e -> e.getRating() == 3)
        .count();


查看完整回答
反對 回復 2022-07-27
  • 5 回答
  • 0 關注
  • 163 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號