TransactionNormalizer { public List<Transaction> normalize(List<Transaction> transactions) { List<Transaction> normalizedTransactions = new ArrayList<>(transactions); ListMultimap<Long, Transaction> transactionByAbsoluteValue = ArrayListMultimap.create(); for (Transaction transaction : transactions) { transactionByAbsoluteValue.put(Math.abs(transaction.getAmount()), transaction); } for (Long amount : transactionByAbsoluteValue.keySet()) { List<Transaction> list = transactionByAbsoluteValue.get(amount); Set<Transaction> canceledOut = Sets.newIdentityHashSet(); for (Transaction transaction : list) { if (canceledOut.contains(transaction)) { continue; } for (Transaction transaction2 : list) { if (transaction.getAmount() == -transaction2.getAmount() && !canceledOut.contains(transaction2)) { canceledOut.add(transaction); canceledOut.add(transaction2); break; } } } normalizedTransactions.removeAll(canceledOut); } return normalizedTransactions; }  List<Transaction> normalize(List<Transaction> transactions);  }
@Test public void normalizeNone() { assertEquals(ImmutableList.of(), normalizer.normalize(ImmutableList.of())); }
@Test public void normalizeTwoEqualPositives() { Transaction transaction1 = mockTransaction(10234); Transaction transaction2 = mockTransaction(10234); assertEquals(ImmutableList.of(transaction1, transaction2), normalizer.normalize(ImmutableList.of(transaction1, transaction2))); }
@Test public void normalizeTwoEqualNegatives() { Transaction transaction1 = mockTransaction(-10234); Transaction transaction2 = mockTransaction(-10234); assertEquals(ImmutableList.of(transaction1, transaction2), normalizer.normalize(ImmutableList.of(transaction1, transaction2))); }
@Test public void normalizeSome() { Transaction transaction0 = mockTransaction(452); Transaction transaction1 = mockTransaction(-10234); Transaction transaction2 = mockTransaction(10234); Transaction transaction3 = mockTransaction(453); assertEquals(ImmutableList.of(transaction0, transaction3), normalizer.normalize(ImmutableList.of(transaction0, transaction1, transaction2, transaction3))); }
@Test public void normalizeSomeDoesntDoubleCancel() { Transaction transaction1 = mockTransaction(-10234); Transaction transaction2 = mockTransaction(10234); Transaction transaction3 = mockTransaction(10234); assertEquals(ImmutableList.of(transaction3), normalizer.normalize(ImmutableList.of(transaction1, transaction2, transaction3))); }