SelfSortingMinimalAmountTransferredOptimizerStrategy implements OptimizerStrategy { @Override public List<Debt> optimize(List<Debt> debts) { final List<Debt> sortedCopy = debts .stream() .sorted(comparingInt(Debt::hashCode)) .collect(toList()); return new MinimalAmountTransferredOptimizer(sortedCopy).getDebtsWithMinimalAmountTransferred(); }  @Override List<Debt> optimize(List<Debt> debts);  }
@Test public void testShouldOptimizeDebtList() { List<Debt> debtList = Arrays.asList( debt(matthias, amount(10), thomas), debt(thomas, amount(3), david), debt(thomas, amount(10), david), debt(david, amount(13), thomasB), debt(jacqueline, amount(7), thomas), debt(thomasB, amount(6), jacqueline), debt(jacqueline, amount(5), thomasB), debt(matthias, amount(4), jacqueline), debt(thomas, amount(13), thomasB), debt(david, amount(17), thomas) ); List<Debt> optimalDebts = sut.optimize(debtList); assertThat(optimalDebts, allOf( Matchers.<Debt>iterableWithSize(5), containsInAnyOrder( debt(matthias, amount(3), thomas), debt(jacqueline, amount(2), thomasB), debt(matthias, amount(11), thomasB), debt(david, amount(5), thomas), debt(david, amount(12), thomasB) ) )); }
@Test public void orderOfDebtsShouldNotInfluenceResults() { List<Debt> debtListA = Arrays.asList( debt(matthias, amount(10), thomas), debt(thomas, amount(3), david), debt(thomas, amount(10), david), debt(david, amount(13), thomasB), debt(jacqueline, amount(7), thomas), debt(thomasB, amount(6), jacqueline), debt(jacqueline, amount(5), thomasB), debt(matthias, amount(4), jacqueline), debt(thomas, amount(13), thomasB), debt(david, amount(17), thomas) ); List<Debt> debtListB = Arrays.asList( debt(david, amount(17), thomas), debt(david, amount(13), thomasB), debt(matthias, amount(4), jacqueline), debt(thomas, amount(13), thomasB), debt(matthias, amount(10), thomas), debt(thomas, amount(10), david), debt(thomas, amount(3), david), debt(thomasB, amount(6), jacqueline), debt(jacqueline, amount(7), thomas), debt(jacqueline, amount(5), thomasB) ); List<Debt> optimalDebtsA = sut.optimize(debtListA); List<Debt> optimalDebtsB = sut.optimize(debtListB); assertThat(optimalDebtsA, equalTo(optimalDebtsB)); }