Java Stream:在类中使用多个类型的组列表

时间:2016-12-30 15:43:10

标签: java java-8 java-stream collectors

我有不同的数据集,如下所示,现在我想通过ClientId + EffDate + Seccode进行分组

    List<Transaction> list = new  ArrayList<Transaction>();


    for (int i=0; i <= 10 ; i++){
        Transaction txn = new Transaction();

        txn.setClientId(i);
        txn.setEffDate("11/11/201"+i);
        txn.setSecCode("PPD");
        list.add(txn);
    }
    for (int i=5; i <= 10 ; i++){
        Transaction txn = new Transaction();

        txn.setClientId(i);
        txn.setEffDate("11/11/201"+i);
        txn.setSecCode("PPD");
        list.add(txn);
    }

我想使用以下标准获取数据

ClientId + EffDate + Seccode获取交易清单

我正在尝试使用以下不完整的代码

 Function<Transaction, List<Object>> keyExtractor = wr ->Arrays.<Object>asList(wr.getClientId(), wr.getEffDate(), wr.getSecCode());

 Map<List<Object>, String> aggData = list.stream().collect(Collectors.groupingBy(keyExtractor).....

非常感谢任何帮助

2 个答案:

答案 0 :(得分:1)

据我所知,你正在努力完成以下任务之一:

  1. 按单个属性(例如,客户端ID)进行的组交易;或
  2. 按所有属性分组交易
  3. (1)要按单个属性进行分组,我建议使用映射到您想要的密钥的classifier(例如,Transaction :: getClientId)。例如:

    Map<Integer, List<Transaction>> byClientId = list.stream()
        .collect(Collectors.collectingAndThen(Collectors.groupingBy(Transaction::getClientId), Collections::unmodifiableMap));
    
    System.out.println(byClientId.entrySet().stream()
        .sorted(Map.Entry.comparingByKey())
        .map(e -> e.getKey().toString() + ": " + e.getValue().stream()
            .map(Object::toString)
            .collect(Collectors.joining(", ")))
        .collect(Collectors.joining("\n")));
    

    (2)要按所有属性进行分组,我建议您使用identify function作为classifier,并记住覆盖Object::equals。例如:

    Map<Transaction, List<Transaction>> byTransaction = list.stream()
        .collect(Collectors.collectingAndThen(Collectors.groupingBy(Function.identity()), Collections::unmodifiableMap));
    
    System.out.println(byTransaction.entrySet().stream()
        .sorted(Map.Entry.comparingByKey(Comparator.comparing(Transaction::getClientId)
            .thenComparing(Transaction::getEffDate)
            .thenComparing(Transaction::getSecCode)))
        .map(e -> e.getKey().toString() + ": " + e.getValue().stream()
            .map(Object::toString)
            .collect(Collectors.joining(", ")))
        .collect(Collectors.joining("\n")));
    

答案 1 :(得分:0)

我使用下面的代码解决了这个问题。

    Test data
    ---------

     List<Transaction> list = new  ArrayList<Transaction>();


    for (int i=0; i <= 10 ; i++){
        Transaction txn = new Transaction();

        txn.setClientId(i);
        txn.setEffDate("11/11/201"+i);
        txn.setSecCode("PPD");
        list.add(txn);
    }
    for (int i=0; i <= 5 ; i++){
        Transaction txn = new Transaction();

        txn.setClientId(i);
        txn.setEffDate("11/11/201"+i);
        txn.setSecCode("PPD");
        list.add(txn);
    }


    solution
    --------
    Map<Key, List<Transaction>> map = list.stream().collect(Collectors.groupingBy(Transaction::getKey));

    for (Key key : map.keySet()){
        System.out.println( "key effect ="+ key.getEffdate() + ", sec code =" +key.getSecCode() + " , client id ="+ key.getClientId());
        for( Transaction txn : map.get(key)){
            System.out.println( txn.getEffDate() + " "+ txn.getSecCode() + " " + txn.getClientId());
        }

    }


     Transaction.java 
     ----------------
     public class Transaction {

private int clientId;

private String secCode;

private String effDate;

public int getClientId() {
    return clientId;
}

public void setClientId(int clientId) {
    this.clientId = clientId;
}

public String getSecCode() {
    return secCode;
}

public void setSecCode(String secCode) {
    this.secCode = secCode;
}

public String getEffDate() {
    return effDate;
}

public void setEffDate(String effDate) {
    this.effDate = effDate;
}



@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + clientId;
    result = prime * result + ((effDate == null) ? 0 : effDate.hashCode());
    result = prime * result + ((secCode == null) ? 0 : secCode.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Transaction other = (Transaction) obj;
    if (clientId != other.clientId)
        return false;
    if (effDate == null) {
        if (other.effDate != null)
            return false;
    } else if (!effDate.equals(other.effDate))
        return false;
    if (secCode == null) {
        if (other.secCode != null)
            return false;
    } else if (!secCode.equals(other.secCode))
        return false;
    return true;
}


public Key getKey() {
    return new Key(clientId, secCode,effDate);
}

class Key {

    public int getClientId() {
    return clientId;
}

public void setClientId(int clientId) {
    this.clientId = clientId;
}


    private int clientId;

    private String secCode;

    private String effdate;


    public Key(int clientId, String secCode,String effdate) {
        this.clientId = clientId;
        this.secCode = secCode;
        this.effdate = effdate;

    }

    public String getSecCode() {
        return secCode;
    }

    public void setSecCode(String secCode) {
        this.secCode = secCode;
    }

    public String getEffdate() {
        return effdate;
    }

    public void setEffdate(String effdate) {
        this.effdate = effdate;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + clientId;
        result = prime * result + ((effdate == null) ? 0 : effdate.hashCode());
        result = prime * result + ((secCode == null) ? 0 : secCode.hashCode());
        return result;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Key other = (Key) obj;
        if (clientId != other.clientId)
            return false;
        if (effdate == null) {
            if (other.effdate != null)
                return false;
        } else if (!effdate.equals(other.effdate))
            return false;
        if (secCode == null) {
            if (other.secCode != null)
                return false;
        } else if (!secCode.equals(other.secCode))
            return false;
        return true;
    }





}