【问题标题】:Check the fields in two objects in list检查列表中两个对象的字段
【发布时间】:2020-06-28 10:35:56
【问题描述】:

我有对象列表:

{
  "rn": "14",
  "time": "2020-06-16 16:47:55",
  "id": 42332392988,
  "termname": "S1160AFB",
  "type": "100",
  "trancode": "110",
  "pan": "4790729949581839",
  "amount": "360.96",
  "approvalcode": "44444"
},
{
  "rn": "15",
  "time": "2020-06-16 16:48:55",
  "id": 42330308379,
  "termname": "S1160AFB",
  "type": "100",
  "trancode": "110",
  "pan": "4149510064617121",
  "amount": "360.96",
  "approvalcode": "55555"
},
{
  "rn": "13",
  "time": "2020-06-16 16:49:11",
  "id": 42332530886,
  "termname": "S1160AFB",
  "type": "420",
  "trancode": "110",
  "pan": "4790729949581839",
  "amount": "360.96",
  "approvalcode": "44444"
}

如果出现以下情况,我需要从列表对象中删除:

  1. 它们具有相同的字段批准代码。 (批准代码 - 唯一。并且不能超过两个相同)
  2. 在具有相同批准代码的两个对象中,您需要检查日期较大的对象,以及该对象类型是否为 420。从列表中删除这两个对象。

我是这样决定的:

  1. 我按批准代码和日期对列表进行排序。

     List<Transaction> filteredTrans = transResponse.getTransaction().stream().sorted(Comparator.comparing(Transaction::approvalcode).thenComparing(Transaction::getTime))
     .collect(Collectors.toList());
    

排序后,我比较两个最接近的对象。

  for (int i=0; i<filteredTrans.size()-1; i++) {
  if (filteredTrans.get(i).getApprovalcode().equals(filteredTrans.get(j).getApprovalcode()) && filteredTrans.get(j).getType().equals("420")) {
      filteredTrans.remove(i);
      filteredTrans.remove(j);
      j++;
  }
}

但我不喜欢代码的第二部分。能否请教一下如何改进?

【问题讨论】:

    标签: java list filter


    【解决方案1】:

    您应该使用地图而不是排序。以下是您可以继续进行此操作的方法

    import java.time.LocalDateTime;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Function;
    import java.util.stream.Collectors;
    
    public class Test {
      static class Transaction {
        String approvalCode;
        LocalDateTime time;
        int type;
    
        public Transaction(String approvalCode, LocalDateTime time, int type) {
          this.approvalCode = approvalCode;
          this.time = time;
          this.type = type;
        }
    
        public int getType() {
          return type;
        }
    
        public LocalDateTime getTime() {
          return time;
        }
    
        public String getApprovalCode() {
          return approvalCode;
        }
    
          @Override
          public String toString() {
              return "Transaction{" +
                      "approvalCode='" + approvalCode + '\'' +
                      ", time=" + time +
                      ", type=" + type +
                      '}';
          }
      }
    
      public static void main(String[] args) {
        List<Transaction> transactions = new ArrayList<>();
        transactions.add(new Transaction("1", LocalDateTime.now(), 420));
        transactions.add(new Transaction("1", LocalDateTime.now(), 11));
        transactions.add(new Transaction("1", LocalDateTime.now(), 12));
        transactions.add(new Transaction("2", LocalDateTime.now(), 13));
        transactions.add(new Transaction("2", LocalDateTime.now(), 14));
        transactions.add(new Transaction("2", LocalDateTime.now(), 420));
        System.out.println(
            transactions.stream()
                .collect(
                    Collectors.toMap(
                        Transaction::getApprovalCode,
                        Function.identity(),
                        (u, v) -> u.getTime().compareTo(v.getTime()) > 0 ? u : v))
                .values()
                .stream()
                .filter(v -> v.getType() != 420)
                .collect(Collectors.toList()));
      }
    }
    

    当遍历一个列表时,不要从同一个列表中删除。它可能导致并发修改异常。相反,将所有必需的元素复制到新列表/使用流过滤器

    【讨论】:

    • 谢谢回答,但如果等于approvalCode并且如果在那个日期类型= 420的情况下,我需要删除这两个对象。例如:List transactions = new ArrayList(); transactions.add(new Transaction("1", LocalDateTime.now(), 420)); transactions.add(new Transaction("1", LocalDateTime.now(), 12)); transactions.add(new Transaction("2", LocalDateTime.now(), 13));从此应该保留 Transaction with approvalCode == 2。
    • 结果:[Transaction{approvalCode='1', time=2020-06-29T02:48:15.828, type=12}] 这将删除approvalCode=2的交易。这不是你的意思吗?
    • approvalCode=2 必须留下。抱歉,如果我的问题表述不当
    • >2.在具有相同批准代码的两个对象中,您需要检查日期较大的对象以及此对象类型是否为 420。从列表中删除这两个对象。用给定的条件回答。
    • 可以,但是同一个approvalcode的object最多只能是2个。不好意思,没马上写
    【解决方案2】:

    谢谢大家的帮助。 这段代码对我有帮助:

    List<Transaction> filteredTrans = transResponse.getTransaction().stream()
        .collect(Collectors.groupingBy(Transaction::getApprovalcode))
        .values()
        .stream()
        .filter(l -> {
            if (l.size() == 1) return true;
            Transaction maxTimeTr = l.stream().max(Comparator.comparing(Transaction::getTime)).orElseThrow();
            return !maxTimeTr.getType().equals("420");
        })
        .flatMap(Collection::stream)
        .collect(Collectors.toList());
    

    【讨论】:

      猜你喜欢
      • 2021-12-03
      • 1970-01-01
      • 2019-11-04
      • 1970-01-01
      • 2016-07-10
      • 1970-01-01
      • 2011-11-26
      • 1970-01-01
      • 2013-05-19
      相关资源
      最近更新 更多