@Test
 public void testMinIndex() {
   List<Integer> ints = IntStreamEx.of(new Random(1), 1000, 5, 47).boxed().toList();
   long expectedMin = IntStreamEx.ofIndices(ints).minBy(ints::get).getAsInt();
   long expectedMax = IntStreamEx.ofIndices(ints).maxBy(ints::get).getAsInt();
   long expectedMinString =
       IntStreamEx.ofIndices(ints).minBy(i -> String.valueOf(ints.get(i))).getAsInt();
   long expectedMaxString =
       IntStreamEx.ofIndices(ints).maxBy(i -> String.valueOf(ints.get(i))).getAsInt();
   Comparator<Integer> cmp = Comparator.comparing(String::valueOf);
   checkCollector(
       "minIndex", OptionalLong.of(expectedMin), ints::stream, MoreCollectors.minIndex());
   checkCollector(
       "maxIndex", OptionalLong.of(expectedMax), ints::stream, MoreCollectors.maxIndex());
   checkCollector(
       "minIndex", OptionalLong.of(expectedMinString), ints::stream, MoreCollectors.minIndex(cmp));
   checkCollector(
       "maxIndex", OptionalLong.of(expectedMaxString), ints::stream, MoreCollectors.maxIndex(cmp));
   Supplier<Stream<String>> supplier = () -> ints.stream().map(Object::toString);
   checkCollector(
       "minIndex", OptionalLong.of(expectedMinString), supplier, MoreCollectors.minIndex());
   checkCollector(
       "maxIndex", OptionalLong.of(expectedMaxString), supplier, MoreCollectors.maxIndex());
   checkCollectorEmpty("minIndex", OptionalLong.empty(), MoreCollectors.<String>minIndex());
   checkCollectorEmpty("maxIndex", OptionalLong.empty(), MoreCollectors.<String>maxIndex());
 }
 @Test
 public void testToBooleanArray() {
   List<Integer> input = IntStreamEx.of(new Random(1), 1000, 1, 100).boxed().toList();
   boolean[] expected = new boolean[input.size()];
   for (int i = 0; i < expected.length; i++) expected[i] = input.get(i) > 50;
   for (StreamExSupplier<Integer> supplier : streamEx(input::stream)) {
     assertArrayEquals(
         supplier.toString(),
         expected,
         supplier.get().collect(MoreCollectors.toBooleanArray(x -> x > 50)));
   }
 }
  @Test
  public void testGreatest() {
    List<Integer> ints = IntStreamEx.of(new Random(1), 1000, 1, 1000).boxed().toList();
    List<Integer> sorted = StreamEx.of(ints).sorted().toList();
    List<Integer> revSorted = StreamEx.of(ints).reverseSorted().toList();
    Comparator<Integer> byString = Comparator.comparing(String::valueOf);
    checkShortCircuitCollector(
        "least(0)", Collections.emptyList(), 0, ints::stream, MoreCollectors.least(0));
    checkCollector("least(5)", sorted.subList(0, 5), ints::stream, MoreCollectors.least(5));
    checkCollector("least(20)", sorted.subList(0, 20), ints::stream, MoreCollectors.least(20));
    checkCollector("least(MAX)", sorted, ints::stream, MoreCollectors.least(Integer.MAX_VALUE));
    checkCollector(
        "least(byString, 20)",
        StreamEx.of(ints).sorted(byString).limit(20).toList(),
        ints::stream,
        MoreCollectors.least(byString, 20));

    checkShortCircuitCollector(
        "greatest(0)", Collections.emptyList(), 0, ints::stream, MoreCollectors.greatest(0));
    checkCollector(
        "greatest(5)", revSorted.subList(0, 5), ints::stream, MoreCollectors.greatest(5));
    checkCollector(
        "greatest(20)", revSorted.subList(0, 20), ints::stream, MoreCollectors.greatest(20));
    checkCollector(
        "greatest(MAX)", revSorted, ints::stream, MoreCollectors.greatest(Integer.MAX_VALUE));
    checkCollector(
        "greatest(byString, 20)",
        StreamEx.of(ints).reverseSorted(byString).limit(20).toList(),
        ints::stream,
        MoreCollectors.greatest(byString, 20));

    Supplier<Stream<Integer>> s = () -> IntStreamEx.range(100).boxed();
    checkCollector("1", IntStreamEx.range(1).boxed().toList(), s, MoreCollectors.least(1));
    checkCollector("2", IntStreamEx.range(2).boxed().toList(), s, MoreCollectors.least(2));
    checkCollector("10", IntStreamEx.range(10).boxed().toList(), s, MoreCollectors.least(10));
    checkCollector("100", IntStreamEx.range(100).boxed().toList(), s, MoreCollectors.least(100));
    checkCollector("200", IntStreamEx.range(100).boxed().toList(), s, MoreCollectors.least(200));
  }
  @Test
  public void testMaxAll() {
    List<String> input = Arrays.asList("a", "bb", "c", "", "cc", "eee", "bb", "ddd");
    checkCollector(
        "maxAll",
        Arrays.asList("eee", "ddd"),
        input::stream,
        MoreCollectors.maxAll(Comparator.comparingInt(String::length)));
    Collector<String, ?, String> maxAllJoin =
        MoreCollectors.maxAll(Comparator.comparingInt(String::length), Collectors.joining(","));
    checkCollector("maxAllJoin", "eee,ddd", input::stream, maxAllJoin);
    checkCollector(
        "minAll",
        1L,
        input::stream,
        MoreCollectors.minAll(Comparator.comparingInt(String::length), Collectors.counting()));
    checkCollector(
        "minAllEmpty",
        Arrays.asList(""),
        input::stream,
        MoreCollectors.minAll(Comparator.comparingInt(String::length)));
    checkCollectorEmpty(
        "maxAll",
        Collections.emptyList(),
        MoreCollectors.maxAll(Comparator.comparingInt(String::length)));
    checkCollectorEmpty("maxAllJoin", "", maxAllJoin);

    List<Integer> ints = IntStreamEx.of(new Random(1), 10000, 1, 1000).boxed().toList();
    List<Integer> expectedMax = getMaxAll(ints, Comparator.naturalOrder());
    List<Integer> expectedMin = getMaxAll(ints, Comparator.reverseOrder());
    Collector<Integer, ?, SimpleEntry<Integer, Long>> downstream =
        MoreCollectors.pairing(
            MoreCollectors.first(),
            Collectors.counting(),
            (opt, cnt) -> new AbstractMap.SimpleEntry<>(opt.get(), cnt));

    checkCollector("maxAll", expectedMax, ints::stream, MoreCollectors.maxAll(Integer::compare));
    checkCollector("minAll", expectedMin, ints::stream, MoreCollectors.minAll());
    checkCollector(
        "entry",
        new SimpleEntry<>(expectedMax.get(0), (long) expectedMax.size()),
        ints::stream,
        MoreCollectors.maxAll(downstream));
    checkCollector(
        "entry",
        new SimpleEntry<>(expectedMin.get(0), (long) expectedMin.size()),
        ints::stream,
        MoreCollectors.minAll(downstream));

    Integer a = new Integer(1), b = new Integer(1), c = new Integer(1000), d = new Integer(1000);
    ints = IntStreamEx.range(10, 100).boxed().append(a, c).prepend(b, d).toList();
    for (StreamExSupplier<Integer> supplier : streamEx(ints::stream)) {
      List<Integer> list = supplier.get().collect(MoreCollectors.maxAll());
      assertEquals(2, list.size());
      assertSame(d, list.get(0));
      assertSame(c, list.get(1));

      list = supplier.get().collect(MoreCollectors.minAll());
      assertEquals(2, list.size());
      assertSame(b, list.get(0));
      assertSame(a, list.get(1));
    }
  }