【问题标题】:With Java 8 streams, How to find items with specific conditions within a specific period使用 Java 8 流,如何在特定时期内查找具有特定条件的项目
【发布时间】:2019-03-17 22:10:44
【问题描述】:

我需要帮助来了解如何在 java 中找到当前在 sql 中完成的内容。我需要使用流在特定时间段内的列表中查找特定数据

场景: 我有一个带有字符串 CustId、即时时间戳、双倍 betAmount 的 Bet 对象

我需要找到每 24 小时超过 100.00 个限制的所有客户,我将如何在 Java 8 中做到这一点?

方法是

public List<String> findLimits(List<Bet> bets){
...
}

样本数据:

note: to be parsed in List<Bet>

A00001    2019-01-15T02:01:10   43.00
A00001    2019-01-15T04:00:00   13.00
A00001    2019-01-15T04:01:15   50.00
B00034    2019-01-15T05:00:00   15.00
A00001    2019-01-15T06:56:20   5.00
B00034    2019-01-15T06:57:00   20.00
C00004    2019-01-15T07:01:00   90.00
C00004    2019-01-15T07:11:00   30.00
B00034    2019-01-17T01:00:00   90.00

预期结果:

["A00001","C00004"] (List<String>)

注意:该列表将包含所有具有不同客户 ID 和时间时间戳的投注

滑动的 24 小时周期和对客户进行分组是我正在尝试解决的一个棘手问题。

【问题讨论】:

  • 按客户 ID 分组;然后过滤条目集以仅包含与您的标准匹配的值;然后丢弃这些值。 “匹配你的标准”位可以只是一个简单的方法,它使用两个指针在点上滑动,跟踪指针之间的赌注总和。
  • 这个关于滑动窗口流操作的答案对stackoverflow.com/a/34159174/2615510有帮助吗?

标签: java java-8


【解决方案1】:

您可以将日期与投注金额的总和对应起来。然后过滤它们。

public List<String> findLimits(List<Bet> bets) {
    return bets.stream()
            .collect(Collectors.toMap(
                    b -> b.getCustId() + LocalDate.ofInstant(b.getTimestamp(), ZoneOffset.UTC).toString(),
                    Bet::getAmount,
                    (o1, o2) -> o1 + o2))
            .entrySet().stream()
            .filter(e -> e.getValue() > 100.0)
            .map(e -> e.getKey().substring(0, e.getKey().length() - LocalDate.EPOCH.toString().length()))
            .collect(Collectors.toList());
}

【讨论】:

    【解决方案2】:

    首先,您可以按客户 ID 对数据进行分组,然后分析 24 小时内的总和。正如您提到的记录按日期升序排序,因此findLimits 方法如下所示:

    class Bet {
        String ID;
        LocalDateTime dateTime;
        BigDecimal value;
    }
    
    public List<String> findLimits(List<Bet> bets) {
        BigDecimal sumLimit = new BigDecimal(100);
        Map<String, List<Bet>> map = new HashMap<String, List<Bet>>();
        List<String> result = new ArrayList<String>();
        for (Bet bet : bets) {
            if (map.get(bet.ID) == null)
                map.put(bet.ID, new ArrayList<Bet>());
            map.get(bet.ID).add(bet);
        }
    
        for (String ID : map.keySet()) {
            List<Bet> betListForCustomer = map.get(ID);
            boolean customerExceededLimit = false;
            for (int i = 0; i < betListForCustomer.size(); i++) {
                LocalDateTime endOfPeriod = betListForCustomer.get(i).dateTime.plusDays(1); //calculating end of 24h period current data
                BigDecimal sum = new BigDecimal(0);
                for (int j = i; j < betListForCustomer.size() //move start period to next dateTime
                        && endOfPeriod.isAfter(betListForCustomer.get(j).dateTime); j++) { //analyzing to the last date in 24h period or end data set
                    sum = sum.add(betListForCustomer.get(j).value);
                }
                if (sum.compareTo(sumLimit) >= 0) { //sum >= 100
                    customerExceededLimit = true;
                    break; //there is no need to analyze this customer, limit exceeded
                }
            }
            if (customerExceededLimit) {
                result.add(ID);
            }
        }
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 2020-02-01
      • 2018-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多