使用Java 8流,如何在特定时期内查找具有特定条件的项目

时间:2019-03-17 22:10:45

标签: java java-8

我需要帮助来找出如何在java中找到当前正在sql中执行的操作。我需要在特定时间内使用流在列表中查找特定数据

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

我需要找到所有每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小时的滑动和将客户分组在一起是我要解决的一个棘手的问题。

2 个答案:

答案 0 :(得分:1)

Firstly you can group data by customer ID and then analyze sums in 24h periods. As you mentioned records are sorted by date ascending, so findLimits method can look like below:

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

答案 1 :(得分:1)

You can map dates with the sum of bet amounts. Then filter them.

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