NonNegativeIntegerSplitterByWeights { public ImmutableMap<E, Integer> split(int numberToSplit) { Preconditions.checkArgument(numberToSplit >= 0, "Quantity to split must be non negative"); if (proportions.isEmpty()) { return ImmutableMap.of(); } ImmutableMap<E, Double> idealAmounts = ImmutableMapFactory.createWithNewValues( proportions, p -> p * numberToSplit); ImmutableMap<E, Integer> roundedDownAmounts = ImmutableMapFactory.createWithNewValues( idealAmounts, idealAmount -> (int) Math.floor(idealAmount)); return assignRemainder(numberToSplit, idealAmounts, roundedDownAmounts); } NonNegativeIntegerSplitterByWeights(ImmutableMap<E, Double> weights); static NonNegativeIntegerSplitterByWeights<E> createWithSorting(
            ImmutableMap<E, Double> weights); static NonNegativeIntegerSplitterByWeights<E> createFromInts(ImmutableMap<E, Integer> weights); static NonNegativeIntegerSplitterByWeights<E> createFromIntsWithSorting(
            ImmutableMap<E, Integer> weights); static ImmutableTable<R, C, Integer> splitByTableWeights(
            ImmutableTable<R, C, Double> weights,
            int numberToSplit); static ImmutableTable<R, C, Integer> splitByIntegerTableWeights(
            ImmutableTable<R, C, Integer> weights,
            int numberToSplit); ImmutableMap<E, Integer> split(int numberToSplit);  }
@Test void testSingleWeight() { NonNegativeIntegerSplitterByWeights<String> splitter = new NonNegativeIntegerSplitterByWeights<>(ImmutableMap.of( "A", 1d)); Assertions.assertEquals(1, (int)splitter.split(1).get("A")); Assertions.assertEquals(100, (int)splitter.split(100).get("A")); }
@Test void testMultipleWeights() { NonNegativeIntegerSplitterByWeights<String> splitter = new NonNegativeIntegerSplitterByWeights<>(ImmutableMap.of( "A", 1d, "B", 2d)); ImmutableMap<String, Integer> splitInts = splitter.split(1); Assertions.assertEquals(0, (int)splitInts.get("A")); Assertions.assertEquals(1, (int)splitInts.get("B")); splitInts = splitter.split(2); Assertions.assertEquals(1, (int)splitInts.get("A")); Assertions.assertEquals(1, (int)splitInts.get("B")); splitInts = splitter.split(100); Assertions.assertEquals(33, (int)splitInts.get("A")); Assertions.assertEquals(67, (int)splitInts.get("B")); splitInts = splitter.split(101); Assertions.assertEquals(34, (int)splitInts.get("A")); Assertions.assertEquals(67, (int)splitInts.get("B")); }
@Test void testWithNoWeights() { NonNegativeIntegerSplitterByWeights<String> splitter = new NonNegativeIntegerSplitterByWeights<>(ImmutableMap.of()); Assertions.assertTrue(splitter.split(1).isEmpty()); Assertions.assertTrue(splitter.split(100).isEmpty()); }
@Test void testSplitSWithLargeRemainder() { NonNegativeIntegerSplitterByWeights<String> splitter = new NonNegativeIntegerSplitterByWeights<>(ImmutableMap.of( "A", 1d, "B", 2d, "C", 3d, "D", 2d)); ImmutableMap<String, Integer> splitInts = splitter.split(7); Assertions.assertEquals(1, (int) splitInts.get("A")); Assertions.assertEquals(2, (int) splitInts.get("B")); Assertions.assertEquals(2, (int) splitInts.get("C")); Assertions.assertEquals(2, (int) splitInts.get("D")); }
@Test void testFavourFirstKeysInWeightMapForTies() { NonNegativeIntegerSplitterByWeights<String> splitter = new NonNegativeIntegerSplitterByWeights<>(ImmutableMap.of( "A", 1d, "B", 2d, "C", 1d )); ImmutableMap<String, Integer> splitInts = splitter.split(2); Assertions.assertEquals(1, (int) splitInts.get("A")); Assertions.assertEquals(1, (int) splitInts.get("B")); Assertions.assertEquals(0, (int) splitInts.get("C")); }