fork download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.Comparator;
  6. import java.util.List;
  7. import java.util.Optional;
  8. import java.util.function.BinaryOperator;
  9. import java.util.stream.Collector;
  10. import java.util.stream.Stream;
  11.  
  12. public class Main {
  13. public static void main(String[] args) {
  14. ArrayList<MyCustomObject> list = new ArrayList<>();
  15. for (int i = 0; i < 10; i++) {
  16. for (int j = 0; j < 3; j++) {
  17. list.add(new MyCustomObject(i));
  18. }
  19. }
  20. Collections.shuffle(list);
  21.  
  22. Comparator<MyCustomObject> compare = Comparator.comparing(MyCustomObject::getIntField);
  23. class Intermediate {
  24. MyCustomObject value = null;
  25. List<MyCustomObject> objects = new ArrayList<>();
  26.  
  27. void add(MyCustomObject c) {
  28. if (objects.isEmpty()) {
  29. value = c;
  30. } else {
  31. int compareResult = compare.compare(c, objects.get(0));
  32. if (compareResult > 0) {
  33. // new max found
  34. System.out.println("new max " + c.intField + ", dropping " + objects.size() + " objects");
  35. value = c;
  36. objects.clear();
  37. } else if (compareResult < 0) {
  38. return;
  39. }
  40. }
  41. objects.add(c);
  42. }
  43. }
  44. BinaryOperator<Intermediate> combiner = (i1, i2) -> {
  45. System.out.printf("combining %d and %d%n", i1.value, i2.value);
  46. Intermediate result = new Intermediate();
  47. Optional<MyCustomObject> max = Stream.of(i1, i2).filter(i -> !i.objects.isEmpty())
  48. .map(i -> i.objects.get(0)).max(compare);
  49. max.ifPresent(m -> {
  50. if (compare.compare(i1.value, m) == 0) {
  51. result.objects.addAll(i1.objects);
  52. }
  53. if (compare.compare(i2.value, m) == 0) {
  54. result.objects.addAll(i2.objects);
  55. }
  56. });
  57. return result;
  58. };
  59. Collector<MyCustomObject, Intermediate, List<MyCustomObject>> collector = Collector.of(Intermediate::new,
  60. Intermediate::add, combiner, i -> i.objects);
  61. System.out.println(list.stream().collect(collector));
  62. }
  63.  
  64. static class MyCustomObject {
  65. private int intField;
  66.  
  67. MyCustomObject(int field) {
  68. intField = field;
  69. }
  70.  
  71. public int getIntField() {
  72. return intField;
  73. }
  74.  
  75. @Override
  76. public String toString() {
  77. return Integer.toString(intField);
  78. }
  79. }
  80. }
  81.  
Success #stdin #stdout 0.22s 34032KB
stdin
Standard input is empty
stdout
new max 3, dropping 1 objects
new max 7, dropping 1 objects
new max 9, dropping 3 objects
[9, 9, 9]