比较和排序列表中的参数化类型?

时间:2016-10-29 18:38:51

标签: java generics comparator

我正在尝试一个简单的程序,该程序可以创建一个银行帐户,并且有与之关联的交易。当我使用原始类型时它可以完美地工作,但是我包含了添加String操作的可能性(例如撤销时的ERROR),现在我不知道如何对列表进行排序以便String操作不会打印出来时,如果已过滤,则会显示;如果已排序,则显示在底部。

完整源代码:

public static void main(String[] args) {
    BankAccount bankAccount = new BankAccount();
    bankAccount.addTransaction(2, TransactionType.DEPOSIT);
    bankAccount.addTransaction(100.66, TransactionType.DEPOSIT);
    bankAccount.addTransaction(2, TransactionType.WITHDRAW);
    bankAccount.addTransaction("ERROR", TransactionType.WITHDRAW);

    List<Transaction> transactions = bankAccount.getTransactions();

    List<Transaction> collect = transactions.stream()
            //Error appears over here, probably due to wrong syntax of the two next lines.
            .sorted(Comparator.comparing((Transaction tr) -> tr.getAmount()).reversed()) 
            .filter(tr -> tr.getAmount() > 0)
            .collect(toList());
    collect.forEach(tr -> System.out.println(tr));
}

private static class BankAccount {
    private List<Transaction> transactions = new ArrayList<>();

    public <T> void addTransaction(T amount, TransactionType transactionType) {
        Transaction transaction = new Transaction(amount, transactionType);
        transactions.add(transaction);
        //return 0;
    }

    public List<Transaction> getTransactions() {
        return Collections.unmodifiableList(transactions);
    }

    @Override
    public String toString() {
        return "BankAccount{" +
                "transactions=" + transactions +
                '}';
    }
}

private static class Transaction<T> {
    private final T amount;
    private final TransactionType transactionType;
    private final Date dateCreated;

    public Transaction(T amount, TransactionType transactionType) {
        this.amount = amount;
        this.transactionType = transactionType;
        this.dateCreated = new Date();
    }

    public T getAmount() {
        return amount;

    }

    public TransactionType getTransactionType() {
        return transactionType;
    }

    public Date getDateCreated() {
        return dateCreated;
    }

    @Override
    public String toString() {
        return "Transaction{" +
                "amount=" + amount +
                ", transactionType=" + transactionType +
                ", dateCreated=" + dateCreated +
                '}';
    }
}

private static enum TransactionType {
    DEPOSIT, WITHDRAW;
}

}

2 个答案:

答案 0 :(得分:0)

您的问题是,当您将Transaction<Double>Transaction<String>混合时,您正在将苹果与橙子进行比较。您的BankAccount只能容纳一种Transaction。它们全部为Transaction<Double>Transaction<String>

现在,因为您没有参数化BankAccount类,所以将其视为Transaction<Object>

解决方案是相应地正确参数化BankAccount和代码。这是使用BankAccount<String>编码的版本。

注意:该示例依赖String数字比较,这不是合理的策略。我移动filter()调用以首先删除“错误”事务。然后,您需要考虑解析回传递给comparing()的函数中的数字。

    public static void main(String[] args) {
    BankAccount<String> bankAccount = new BankAccount<>();
    bankAccount.addTransaction(Double.toString(2.00), TransactionType.DEPOSIT);
    bankAccount.addTransaction(Double.toString(100.66), TransactionType.DEPOSIT);
    bankAccount.addTransaction(Double.toString(2.00), TransactionType.WITHDRAW);
    bankAccount.addTransaction("ERROR", TransactionType.WITHDRAW);

    List<Transaction<String>> transactions = bankAccount.getTransactions();

    List<Transaction<String>> collect = transactions.stream()
            .filter(tr -> !tr.getAmount().equals("ERROR"))
            .sorted(Comparator.<Transaction<String>, String> comparing(transaction -> transaction.getAmount()).reversed())
            .collect(Collectors.toList());

    collect.forEach(tr -> System.out.println(tr.getAmount() + " " + tr.getType().name()));
}

public static class BankAccount<T> {

    private List<Transaction<T>> transactions = new ArrayList<>();

    public void addTransaction(T amount, TransactionType transactionType) {
        Transaction<T> transaction = new Transaction <>(amount, transactionType);
        transactions.add(transaction);
    }

    public List<Transaction<T>> getTransactions() {
        return Collections.unmodifiableList(transactions);
    }
}

public static class Transaction<T> {
    private final T amount;
    private final TransactionType transactionType;
    private final Date dateCreated;

    public Transaction(T amount, TransactionType transactionType) {
        this.amount = amount;
        this.transactionType = transactionType;
        this.dateCreated = new Date();
    }

    public T getAmount() {
        return amount;
    }

    public TransactionType getType(){
        return transactionType;
    }

    public Date getDateCreated(){
        return dateCreated;
    }

}

public enum TransactionType {
    DEPOSIT, WITHDRAW;
}

答案 1 :(得分:0)

如果你想比较(排序)不同类型的对象,为什么不为你编写自己的比较器呢?

示例:

{{1}}