• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

amaembo / streamex / #673

29 Nov 2023 08:51AM UTC coverage: 99.69%. Remained the same
#673

push

web-flow
Merge pull request #274 from Kivanval/fix/desc

Correcting a comment in StreamEx.java

5787 of 5805 relevant lines covered (99.69%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.01
/src/main/java/one/util/streamex/Internals.java
1
/*
2
 * Copyright 2015, 2023 StreamEx contributors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package one.util.streamex;
17

18
import java.math.BigDecimal;
19
import java.math.BigInteger;
20
import java.math.MathContext;
21
import java.nio.ByteOrder;
22
import java.util.AbstractCollection;
23
import java.util.AbstractMap;
24
import java.util.AbstractSet;
25
import java.util.Arrays;
26
import java.util.BitSet;
27
import java.util.EnumSet;
28
import java.util.Iterator;
29
import java.util.Map;
30
import java.util.Map.Entry;
31
import java.util.Objects;
32
import java.util.Optional;
33
import java.util.OptionalDouble;
34
import java.util.OptionalInt;
35
import java.util.OptionalLong;
36
import java.util.Set;
37
import java.util.Spliterator;
38
import java.util.function.BiConsumer;
39
import java.util.function.BinaryOperator;
40
import java.util.function.Consumer;
41
import java.util.function.Function;
42
import java.util.function.ObjDoubleConsumer;
43
import java.util.function.ObjIntConsumer;
44
import java.util.function.ObjLongConsumer;
45
import java.util.function.Predicate;
46
import java.util.function.Supplier;
47
import java.util.stream.Collector;
48
import java.util.stream.Collector.Characteristics;
49

50
/* package */interface Internals {
51
    int INITIAL_SIZE = 128;
52
    Function<int[], Integer> UNBOX_INT = box -> box[0];
1✔
53
    Function<long[], Long> UNBOX_LONG = box -> box[0];
1✔
54
    Function<double[], Double> UNBOX_DOUBLE = box -> box[0];
1✔
55
    Object NONE = new Object();
1✔
56
    Set<Characteristics> NO_CHARACTERISTICS = EnumSet.noneOf(Characteristics.class);
1✔
57
    Set<Characteristics> UNORDERED_CHARACTERISTICS = EnumSet.of(Characteristics.UNORDERED);
1✔
58
    Set<Characteristics> UNORDERED_ID_CHARACTERISTICS = EnumSet.of(Characteristics.UNORDERED,
1✔
59
        Characteristics.IDENTITY_FINISH);
60
    Set<Characteristics> ID_CHARACTERISTICS = EnumSet.of(Characteristics.IDENTITY_FINISH);
1✔
61
    boolean IMMUTABLE_TO_LIST = isImmutableToSetToList();
1✔
62

63
    static boolean isImmutableToSetToList() {
64
        try {
65
            return Boolean.parseBoolean(System.getProperty("streamex.default.immutable", "false"));
1✔
66
        } catch (SecurityException e) {
×
67
            return false;
×
68
        }
69
    }
70

71
    static void checkNonNegative(String name, int value) {
72
        if (value < 0) {
1✔
73
            throw new IllegalArgumentException(name + " must be non-negative: " + value);
1✔
74
        }
75
    }
1✔
76

77
    final class ByteBuffer {
78
        int size = 0;
1✔
79
        byte[] data;
80

81
        ByteBuffer() {
1✔
82
            data = new byte[INITIAL_SIZE];
1✔
83
        }
1✔
84

85
        ByteBuffer(int size) {
1✔
86
            data = new byte[size];
1✔
87
        }
1✔
88

89
        void add(int n) {
90
            if (data.length == size) {
1✔
91
                data = Arrays.copyOf(data, data.length * 2);
1✔
92
            }
93
            data[size++] = (byte) n;
1✔
94
        }
1✔
95

96
        void addUnsafe(int n) {
97
            data[size++] = (byte) n;
1✔
98
        }
1✔
99

100
        void addAll(ByteBuffer buf) {
101
            if (data.length < buf.size + size) {
1✔
102
                data = Arrays.copyOf(data, buf.size + size);
1✔
103
            }
104
            System.arraycopy(buf.data, 0, data, size, buf.size);
1✔
105
            size += buf.size;
1✔
106
        }
1✔
107

108
        byte[] toArray() {
109
            return data.length == size ? data : Arrays.copyOfRange(data, 0, size);
1✔
110
        }
111
    }
112

113
    final class CharBuffer {
114
        int size = 0;
1✔
115
        char[] data;
116

117
        CharBuffer() {
1✔
118
            data = new char[INITIAL_SIZE];
1✔
119
        }
1✔
120

121
        CharBuffer(int size) {
1✔
122
            data = new char[size];
1✔
123
        }
1✔
124

125
        void add(int n) {
126
            if (data.length == size) {
1✔
127
                data = Arrays.copyOf(data, data.length * 2);
1✔
128
            }
129
            data[size++] = (char) n;
1✔
130
        }
1✔
131

132
        void addUnsafe(int n) {
133
            data[size++] = (char) n;
1✔
134
        }
1✔
135

136
        void addAll(CharBuffer buf) {
137
            if (data.length < buf.size + size) {
1✔
138
                data = Arrays.copyOf(data, buf.size + size);
1✔
139
            }
140
            System.arraycopy(buf.data, 0, data, size, buf.size);
1✔
141
            size += buf.size;
1✔
142
        }
1✔
143

144
        char[] toArray() {
145
            return data.length == size ? data : Arrays.copyOfRange(data, 0, size);
1✔
146
        }
147
    }
148

149
    final class ShortBuffer {
150
        int size = 0;
1✔
151
        short[] data;
152

153
        ShortBuffer() {
1✔
154
            data = new short[INITIAL_SIZE];
1✔
155
        }
1✔
156

157
        ShortBuffer(int size) {
1✔
158
            data = new short[size];
1✔
159
        }
1✔
160

161
        void add(int n) {
162
            if (data.length == size) {
1✔
163
                data = Arrays.copyOf(data, data.length * 2);
1✔
164
            }
165
            data[size++] = (short) n;
1✔
166
        }
1✔
167

168
        void addUnsafe(int n) {
169
            data[size++] = (short) n;
1✔
170
        }
1✔
171

172
        void addAll(ShortBuffer buf) {
173
            if (data.length < buf.size + size) {
1✔
174
                data = Arrays.copyOf(data, buf.size + size);
1✔
175
            }
176
            System.arraycopy(buf.data, 0, data, size, buf.size);
1✔
177
            size += buf.size;
1✔
178
        }
1✔
179

180
        short[] toArray() {
181
            return data.length == size ? data : Arrays.copyOfRange(data, 0, size);
1✔
182
        }
183
    }
184

185
    final class FloatBuffer {
186
        int size = 0;
1✔
187
        float[] data;
188

189
        FloatBuffer() {
1✔
190
            data = new float[INITIAL_SIZE];
1✔
191
        }
1✔
192

193
        FloatBuffer(int size) {
1✔
194
            data = new float[size];
1✔
195
        }
1✔
196

197
        void add(double n) {
198
            if (data.length == size) {
1✔
199
                data = Arrays.copyOf(data, data.length * 2);
1✔
200
            }
201
            data[size++] = (float) n;
1✔
202
        }
1✔
203

204
        void addUnsafe(double n) {
205
            data[size++] = (float) n;
1✔
206
        }
1✔
207

208
        void addAll(FloatBuffer buf) {
209
            if (data.length < buf.size + size) {
1✔
210
                data = Arrays.copyOf(data, buf.size + size);
1✔
211
            }
212
            System.arraycopy(buf.data, 0, data, size, buf.size);
1✔
213
            size += buf.size;
1✔
214
        }
1✔
215

216
        float[] toArray() {
217
            return data.length == size ? data : Arrays.copyOfRange(data, 0, size);
1✔
218
        }
219
    }
220

221
    final class IntBuffer {
222
        int size = 0;
1✔
223
        int[] data;
224

225
        IntBuffer() {
1✔
226
            data = new int[INITIAL_SIZE];
1✔
227
        }
1✔
228

229
        IntBuffer(int size) {
1✔
230
            data = new int[size];
1✔
231
        }
1✔
232

233
        void add(int n) {
234
            if (data.length == size) {
1✔
235
                data = Arrays.copyOf(data, data.length * 2);
1✔
236
            }
237
            data[size++] = n;
1✔
238
        }
1✔
239

240
        void addAll(IntBuffer buf) {
241
            if (data.length < buf.size + size) {
1✔
242
                data = Arrays.copyOf(data, buf.size + size);
1✔
243
            }
244
            System.arraycopy(buf.data, 0, data, size, buf.size);
1✔
245
            size += buf.size;
1✔
246
        }
1✔
247
        
248
        IntStreamEx stream() {
249
            return IntStreamEx.of(data, 0, size);
1✔
250
        }
251

252
        int[] toArray() {
253
            return data.length == size ? data : Arrays.copyOfRange(data, 0, size);
1✔
254
        }
255
    }
256

257
    final class LongBuffer {
258
        int size = 0;
1✔
259
        long[] data;
260

261
        LongBuffer() {
1✔
262
            data = new long[INITIAL_SIZE];
1✔
263
        }
1✔
264

265
        LongBuffer(int size) {
1✔
266
            data = new long[size];
1✔
267
        }
1✔
268

269
        void add(long n) {
270
            if (data.length == size) {
1✔
271
                data = Arrays.copyOf(data, data.length * 2);
1✔
272
            }
273
            data[size++] = n;
1✔
274
        }
1✔
275

276
        void addAll(LongBuffer buf) {
277
            if (data.length < buf.size + size) {
1✔
278
                data = Arrays.copyOf(data, buf.size + size);
1✔
279
            }
280
            System.arraycopy(buf.data, 0, data, size, buf.size);
1✔
281
            size += buf.size;
1✔
282
        }
1✔
283

284
        LongStreamEx stream() {
285
            return LongStreamEx.of(data, 0, size);
1✔
286
        }
287

288
        long[] toArray() {
289
            return data.length == size ? data : Arrays.copyOfRange(data, 0, size);
1✔
290
        }
291
    }
292

293
    final class DoubleBuffer {
294
        int size = 0;
1✔
295
        double[] data;
296

297
        DoubleBuffer() {
1✔
298
            data = new double[INITIAL_SIZE];
1✔
299
        }
1✔
300

301
        DoubleBuffer(int size) {
1✔
302
            data = new double[size];
1✔
303
        }
1✔
304

305
        void add(double n) {
306
            if (data.length == size) {
1✔
307
                data = Arrays.copyOf(data, data.length * 2);
1✔
308
            }
309
            data[size++] = n;
1✔
310
        }
1✔
311

312
        void addAll(DoubleBuffer buf) {
313
            if (data.length < buf.size + size) {
1✔
314
                data = Arrays.copyOf(data, buf.size + size);
1✔
315
            }
316
            System.arraycopy(buf.data, 0, data, size, buf.size);
1✔
317
            size += buf.size;
1✔
318
        }
1✔
319

320
        DoubleStreamEx stream() {
321
            return DoubleStreamEx.of(data, 0, size);
1✔
322
        }
323

324
        double[] toArray() {
325
            return data.length == size ? data : Arrays.copyOfRange(data, 0, size);
1✔
326
        }
327
    }
328

329
    final class BooleanMap<T> extends AbstractMap<Boolean, T> {
330
        T trueValue, falseValue;
331

332
        BooleanMap(T trueValue, T falseValue) {
1✔
333
            this.trueValue = trueValue;
1✔
334
            this.falseValue = falseValue;
1✔
335
        }
1✔
336

337
        @Override
338
        public boolean containsKey(Object key) {
339
            return key instanceof Boolean;
1✔
340
        }
341

342
        @Override
343
        public T get(Object key) {
344
            if (Boolean.TRUE.equals(key))
1✔
345
                return trueValue;
1✔
346
            if (Boolean.FALSE.equals(key))
1✔
347
                return falseValue;
1✔
348
            return null;
1✔
349
        }
350

351
        @Override
352
        public Set<Map.Entry<Boolean, T>> entrySet() {
353
            return new AbstractSet<Map.Entry<Boolean, T>>() {
1✔
354
                @Override
355
                public Iterator<Map.Entry<Boolean, T>> iterator() {
356
                    return Arrays.<Map.Entry<Boolean, T>>asList(new SimpleEntry<>(Boolean.TRUE, trueValue),
1✔
357
                        new SimpleEntry<>(Boolean.FALSE, falseValue)).iterator();
1✔
358
                }
359

360
                @Override
361
                public int size() {
362
                    return 2;
1✔
363
                }
364
            };
365
        }
366

367
        @Override
368
        public int size() {
369
            return 2;
1✔
370
        }
371

372
        @SuppressWarnings({ "unchecked", "rawtypes" })
373
        static <A, R> PartialCollector<BooleanMap<A>, Map<Boolean, R>> partialCollector(Collector<?, A, R> downstream) {
374
            Supplier<A> downstreamSupplier = downstream.supplier();
1✔
375
            Supplier<BooleanMap<A>> supplier = () -> new BooleanMap<>(downstreamSupplier.get(), downstreamSupplier
1✔
376
                    .get());
1✔
377
            BinaryOperator<A> downstreamCombiner = downstream.combiner();
1✔
378
            BiConsumer<BooleanMap<A>, BooleanMap<A>> merger = (left, right) -> {
1✔
379
                left.trueValue = downstreamCombiner.apply(left.trueValue, right.trueValue);
1✔
380
                left.falseValue = downstreamCombiner.apply(left.falseValue, right.falseValue);
1✔
381
            };
1✔
382
            if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
1✔
383
                return (PartialCollector) new PartialCollector<>(supplier, merger, Function.identity(),
1✔
384
                        ID_CHARACTERISTICS);
385
            }
386
            Function<A, R> downstreamFinisher = downstream.finisher();
1✔
387
            return new PartialCollector<>(supplier, merger, par -> new BooleanMap<>(downstreamFinisher
1✔
388
                    .apply(par.trueValue), downstreamFinisher.apply(par.falseValue)), NO_CHARACTERISTICS);
1✔
389
        }
390
    }
391

392
    abstract class BaseCollector<T, A, R> implements MergingCollector<T, A, R> {
393
        final Supplier<A> supplier;
394
        final BiConsumer<A, A> merger;
395
        final Function<A, R> finisher;
396
        final Set<Characteristics> characteristics;
397

398
        BaseCollector(Supplier<A> supplier, BiConsumer<A, A> merger, Function<A, R> finisher,
399
                Set<Characteristics> characteristics) {
1✔
400
            this.supplier = supplier;
1✔
401
            this.merger = merger;
1✔
402
            this.finisher = finisher;
1✔
403
            this.characteristics = characteristics;
1✔
404
        }
1✔
405

406
        @Override
407
        public Set<Characteristics> characteristics() {
408
            return characteristics;
1✔
409
        }
410

411
        @Override
412
        public Supplier<A> supplier() {
413
            return supplier;
1✔
414
        }
415

416
        @Override
417
        public Function<A, R> finisher() {
418
            return finisher;
1✔
419
        }
420

421
        @Override
422
        public BiConsumer<A, A> merger() {
423
            return merger;
1✔
424
        }
425
    }
426

427
    final class PartialCollector<A, R> extends BaseCollector<Object, A, R> {
428
        PartialCollector(Supplier<A> supplier, BiConsumer<A, A> merger, Function<A, R> finisher,
429
                Set<Characteristics> characteristics) {
430
            super(supplier, merger, finisher, characteristics);
1✔
431
        }
1✔
432

433
        @Override
434
        public BiConsumer<A, Object> accumulator() {
435
            throw new UnsupportedOperationException();
1✔
436
        }
437

438
        IntCollector<A, R> asInt(ObjIntConsumer<A> intAccumulator) {
439
            return new IntCollectorImpl<>(supplier, intAccumulator, merger, finisher, characteristics);
1✔
440
        }
441

442
        LongCollector<A, R> asLong(ObjLongConsumer<A> longAccumulator) {
443
            return new LongCollectorImpl<>(supplier, longAccumulator, merger, finisher, characteristics);
1✔
444
        }
445

446
        DoubleCollector<A, R> asDouble(ObjDoubleConsumer<A> doubleAccumulator) {
447
            return new DoubleCollectorImpl<>(supplier, doubleAccumulator, merger, finisher, characteristics);
1✔
448
        }
449

450
        <T> Collector<T, A, R> asRef(BiConsumer<A, T> accumulator) {
451
            return Collector.of(supplier, accumulator, combiner(), finisher, characteristics
1✔
452
                    .toArray(new Characteristics[0]));
1✔
453
        }
454

455
        <T> Collector<T, A, R> asCancellable(BiConsumer<A, T> accumulator, Predicate<A> finished) {
456
            return new CancellableCollectorImpl<>(supplier, accumulator, combiner(), finisher, finished,
1✔
457
                    characteristics);
458
        }
459

460
        static PartialCollector<int[], Integer> intSum() {
461
            return new PartialCollector<>(() -> new int[1], (box1, box2) -> box1[0] += box2[0], UNBOX_INT,
1✔
462
                    UNORDERED_CHARACTERISTICS);
463
        }
464

465
        static PartialCollector<long[], Long> longSum() {
466
            return new PartialCollector<>(() -> new long[1], (box1, box2) -> box1[0] += box2[0], UNBOX_LONG,
1✔
467
                    UNORDERED_CHARACTERISTICS);
468
        }
469

470
        static PartialCollector<ObjIntBox<BitSet>, boolean[]> booleanArray() {
471
            return new PartialCollector<>(() -> new ObjIntBox<>(new BitSet(), 0), (box1, box2) -> {
1✔
472
                box2.a.stream().forEach(i -> box1.a.set(i + box1.b));
1✔
473
                box1.b = StrictMath.addExact(box1.b, box2.b);
1✔
474
            }, box -> {
1✔
475
                boolean[] res = new boolean[box.b];
1✔
476
                box.a.stream().forEach(i -> res[i] = true);
1✔
477
                return res;
1✔
478
            }, NO_CHARACTERISTICS);
479
        }
480

481
        @SuppressWarnings("unchecked")
482
        static <K, D, A, M extends Map<K, D>> PartialCollector<Map<K, A>, M> grouping(Supplier<M> mapFactory,
483
                Collector<?, A, D> downstream) {
484
            BinaryOperator<A> downstreamMerger = downstream.combiner();
1✔
485
            BiConsumer<Map<K, A>, Map<K, A>> merger = (map1, map2) -> {
1✔
486
                for (Map.Entry<K, A> e : map2.entrySet())
1✔
487
                    map1.merge(e.getKey(), e.getValue(), downstreamMerger);
1✔
488
            };
1✔
489

490
            if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
1✔
491
                return (PartialCollector<Map<K, A>, M>) new PartialCollector<>((Supplier<Map<K, A>>) mapFactory,
1✔
492
                        merger, Function.identity(), ID_CHARACTERISTICS);
1✔
493
            }
494
            Function<A, D> downstreamFinisher = downstream.finisher();
1✔
495
            return new PartialCollector<>((Supplier<Map<K, A>>) mapFactory, merger, map -> {
1✔
496
                map.replaceAll((k, v) -> ((Function<A, A>) downstreamFinisher).apply(v));
1✔
497
                return (M) map;
1✔
498
            }, NO_CHARACTERISTICS);
499
        }
500

501
        static PartialCollector<StringBuilder, String> joining(CharSequence delimiter, CharSequence prefix,
502
                CharSequence suffix, boolean hasPS) {
503
            BiConsumer<StringBuilder, StringBuilder> merger = (sb1, sb2) -> {
1✔
504
                if (sb2.length() > 0) {
1✔
505
                    if (sb1.length() > 0)
1✔
506
                        sb1.append(delimiter);
1✔
507
                    sb1.append(sb2);
1✔
508
                }
509
            };
1✔
510
            Supplier<StringBuilder> supplier = StringBuilder::new;
1✔
511
            if (hasPS)
1✔
512
                return new PartialCollector<>(supplier, merger, sb -> String.valueOf(prefix) + sb + suffix,
1✔
513
                        NO_CHARACTERISTICS);
514
            return new PartialCollector<>(supplier, merger, StringBuilder::toString, NO_CHARACTERISTICS);
1✔
515
        }
516
    }
517

518
    final class CancellableCollectorImpl<T, A, R> extends CancellableCollector<T, A, R> {
519
        private final Supplier<A> supplier;
520
        private final BiConsumer<A, T> accumulator;
521
        private final BinaryOperator<A> combiner;
522
        private final Function<A, R> finisher;
523
        private final Predicate<A> finished;
524
        private final Set<Characteristics> characteristics;
525

526
        CancellableCollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner,
527
                                 Function<A, R> finisher, Predicate<A> finished,
528
                                 Set<java.util.stream.Collector.Characteristics> characteristics) {
1✔
529
            this.supplier = supplier;
1✔
530
            this.accumulator = accumulator;
1✔
531
            this.combiner = combiner;
1✔
532
            this.finisher = finisher;
1✔
533
            this.finished = finished;
1✔
534
            this.characteristics = characteristics;
1✔
535
        }
1✔
536

537
        @Override
538
        public Supplier<A> supplier() {
539
            return supplier;
1✔
540
        }
541

542
        @Override
543
        public BiConsumer<A, T> accumulator() {
544
            return accumulator;
1✔
545
        }
546

547
        @Override
548
        public BinaryOperator<A> combiner() {
549
            return combiner;
1✔
550
        }
551

552
        @Override
553
        public Function<A, R> finisher() {
554
            return finisher;
1✔
555
        }
556

557
        @Override
558
        public Set<Characteristics> characteristics() {
559
            return characteristics;
1✔
560
        }
561

562
        @Override
563
        Predicate<A> finished() {
564
            return finished;
1✔
565
        }
566
    }
567

568
    final class IntCollectorImpl<A, R> extends BaseCollector<Integer, A, R> implements IntCollector<A, R> {
569
        private final ObjIntConsumer<A> intAccumulator;
570

571
        IntCollectorImpl(Supplier<A> supplier, ObjIntConsumer<A> intAccumulator, BiConsumer<A, A> merger,
572
                         Function<A, R> finisher, Set<Characteristics> characteristics) {
573
            super(supplier, merger, finisher, characteristics);
1✔
574
            this.intAccumulator = intAccumulator;
1✔
575
        }
1✔
576

577
        @Override
578
        public ObjIntConsumer<A> intAccumulator() {
579
            return intAccumulator;
1✔
580
        }
581
    }
582

583
    final class LongCollectorImpl<A, R> extends BaseCollector<Long, A, R> implements LongCollector<A, R> {
584
        private final ObjLongConsumer<A> longAccumulator;
585

586
        LongCollectorImpl(Supplier<A> supplier, ObjLongConsumer<A> longAccumulator, BiConsumer<A, A> merger,
587
                          Function<A, R> finisher, Set<Characteristics> characteristics) {
588
            super(supplier, merger, finisher, characteristics);
1✔
589
            this.longAccumulator = longAccumulator;
1✔
590
        }
1✔
591

592
        @Override
593
        public ObjLongConsumer<A> longAccumulator() {
594
            return longAccumulator;
1✔
595
        }
596
    }
597

598
    final class DoubleCollectorImpl<A, R> extends BaseCollector<Double, A, R> implements DoubleCollector<A, R> {
599
        private final ObjDoubleConsumer<A> doubleAccumulator;
600

601
        DoubleCollectorImpl(Supplier<A> supplier, ObjDoubleConsumer<A> doubleAccumulator,
602
                            BiConsumer<A, A> merger, Function<A, R> finisher, Set<Characteristics> characteristics) {
603
            super(supplier, merger, finisher, characteristics);
1✔
604
            this.doubleAccumulator = doubleAccumulator;
1✔
605
        }
1✔
606

607
        @Override
608
        public ObjDoubleConsumer<A> doubleAccumulator() {
609
            return doubleAccumulator;
1✔
610
        }
611
    }
612

613
    class Box<A> implements Consumer<A> {
614
        A a;
615
        
616
        Box() {
1✔
617
        }
1✔
618
        
619
        Box(A obj) {
1✔
620
            this.a = obj;
1✔
621
        }
1✔
622

623
        @Override
624
        public void accept(A a) {
625
            this.a = a;
1✔
626
        }
1✔
627

628
        static <A, R> PartialCollector<Box<A>, R> partialCollector(Collector<?, A, R> c) {
629
            Supplier<A> supplier = c.supplier();
1✔
630
            BinaryOperator<A> combiner = c.combiner();
1✔
631
            Function<A, R> finisher = c.finisher();
1✔
632
            return new PartialCollector<>(() -> new Box<>(supplier.get()), (box1, box2) -> box1.a = combiner.apply(
1✔
633
                box1.a, box2.a), box -> finisher.apply(box.a), NO_CHARACTERISTICS);
1✔
634
        }
635

636
        static <A> Optional<A> asOptional(Box<A> box) {
637
            return box == null ? Optional.empty() : Optional.of(box.a);
1✔
638
        }
639
    }
640

641
    /**
642
     * A box of two elements with special equality semantics: only the second element matters for equality.
643
     * 
644
     * @param <A> type of the first element
645
     * @param <B> type of the second element
646
     */
647
    final class PairBox<A, B> extends Box<A> {
648
        B b;
649

650
        PairBox(A a, B b) {
651
            super(a);
1✔
652
            this.b = b;
1✔
653
        }
1✔
654

655
        static <T> PairBox<T, T> single(T a) {
656
            return new PairBox<>(a, a);
1✔
657
        }
658

659
        @Override
660
        public int hashCode() {
661
            return Objects.hashCode(b);
1✔
662
        }
663

664
        @Override
665
        public boolean equals(Object obj) {
666
            return obj != null && obj.getClass() == PairBox.class && Objects.equals(b, ((PairBox<?, ?>) obj).b);
1✔
667
        }
668
    }
669

670
    final class ObjIntBox<A> extends Box<A> implements Entry<Integer, A> {
671
        int b;
672

673
        ObjIntBox(A a, int b) {
674
            super(a);
1✔
675
            this.b = b;
1✔
676
        }
1✔
677

678
        @Override
679
        public Integer getKey() {
680
            return b;
1✔
681
        }
682

683
        @Override
684
        public A getValue() {
685
            return a;
1✔
686
        }
687

688
        @Override
689
        public A setValue(A value) {
690
            throw new UnsupportedOperationException();
1✔
691
        }
692

693
        @Override
694
        public int hashCode() {
695
            return Integer.hashCode(b) ^ (a == null ? 0 : a.hashCode());
1✔
696
        }
697

698
        @Override
699
        public boolean equals(Object o) {
700
            if (!(o instanceof Map.Entry))
1✔
701
                return false;
1✔
702
            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1✔
703
            return getKey().equals(e.getKey()) && Objects.equals(a, e.getValue());
1✔
704
        }
705

706
        @Override
707
        public String toString() {
708
            return b + "=" + a;
1✔
709
        }
710
    }
711

712
    final class ObjLongBox<A> extends Box<A> implements Entry<A, Long> {
713
        long b;
714

715
        ObjLongBox(A a, long b) {
716
            super(a);
1✔
717
            this.b = b;
1✔
718
        }
1✔
719

720
        @Override
721
        public A getKey() {
722
            return a;
1✔
723
        }
724

725
        @Override
726
        public Long getValue() {
727
            return b;
1✔
728
        }
729

730
        @Override
731
        public Long setValue(Long value) {
732
            throw new UnsupportedOperationException();
1✔
733
        }
734

735
        @Override
736
        public int hashCode() {
737
            return Long.hashCode(b) ^ (a == null ? 0 : a.hashCode());
1✔
738
        }
739

740
        @Override
741
        public boolean equals(Object o) {
742
            if (!(o instanceof Map.Entry))
1✔
743
                return false;
1✔
744
            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1✔
745
            return getValue().equals(e.getValue()) && Objects.equals(a, e.getKey());
1✔
746
        }
747

748
        @Override
749
        public String toString() {
750
            return a + "=" + b;
1✔
751
        }
752
    }
753

754
    final class ObjDoubleBox<A> extends Box<A> {
755
        double b;
756

757
        ObjDoubleBox(A a, double b) {
758
            super(a);
1✔
759
            this.b = b;
1✔
760
        }
1✔
761
    }
762

763
    final class PrimitiveBox {
1✔
764
        int i;
765
        double d;
766
        long l;
767
        boolean b;
768

769
        OptionalInt asInt() {
770
            return b ? OptionalInt.of(i) : OptionalInt.empty();
1✔
771
        }
772

773
        OptionalLong asLong() {
774
            return b ? OptionalLong.of(l) : OptionalLong.empty();
1✔
775
        }
776

777
        OptionalDouble asDouble() {
778
            return b ? OptionalDouble.of(d) : OptionalDouble.empty();
1✔
779
        }
780

781
        static final BiConsumer<PrimitiveBox, PrimitiveBox> MAX_LONG = (box1, box2) -> {
1✔
782
            if (box2.b && (!box1.b || box1.l < box2.l)) {
1✔
783
                box1.from(box2);
1✔
784
            }
785
        };
1✔
786

787
        static final BiConsumer<PrimitiveBox, PrimitiveBox> MIN_LONG = (box1, box2) -> {
1✔
788
            if (box2.b && (!box1.b || box1.l > box2.l)) {
1✔
789
                box1.from(box2);
1✔
790
            }
791
        };
1✔
792

793
        static final BiConsumer<PrimitiveBox, PrimitiveBox> MAX_INT = (box1, box2) -> {
1✔
794
            if (box2.b && (!box1.b || box1.i < box2.i)) {
1✔
795
                box1.from(box2);
1✔
796
            }
797
        };
1✔
798

799
        static final BiConsumer<PrimitiveBox, PrimitiveBox> MIN_INT = (box1, box2) -> {
1✔
800
            if (box2.b && (!box1.b || box1.i > box2.i)) {
1✔
801
                box1.from(box2);
1✔
802
            }
803
        };
1✔
804

805
        static final BiConsumer<PrimitiveBox, PrimitiveBox> MAX_DOUBLE = (box1, box2) -> {
1✔
806
            if (box2.b && (!box1.b || Double.compare(box1.d, box2.d) < 0)) {
1✔
807
                box1.from(box2);
1✔
808
            }
809
        };
1✔
810

811
        static final BiConsumer<PrimitiveBox, PrimitiveBox> MIN_DOUBLE = (box1, box2) -> {
1✔
812
            if (box2.b && (!box1.b || Double.compare(box1.d, box2.d) > 0)) {
1✔
813
                box1.from(box2);
1✔
814
            }
815
        };
1✔
816

817
        public void from(PrimitiveBox box) {
818
            b = box.b;
1✔
819
            i = box.i;
1✔
820
            d = box.d;
1✔
821
            l = box.l;
1✔
822
        }
1✔
823
    }
824

825
    final class AverageLong {
1✔
826
        long hi, lo, cnt;
827

828
        public void accept(long val) {
829
            cnt++;
1✔
830
            int cmp = Long.compareUnsigned(lo, lo += val);
1✔
831
            if (val > 0) {
1✔
832
                if (cmp > 0)
1✔
833
                    hi++;
1✔
834
            } else if (cmp < 0)
1✔
835
                hi--;
1✔
836
        }
1✔
837

838
        public AverageLong combine(AverageLong other) {
839
            cnt += other.cnt;
1✔
840
            hi += other.hi;
1✔
841
            if (Long.compareUnsigned(lo, lo += other.lo) > 0) {
1✔
842
                hi++;
1✔
843
            }
844
            return this;
1✔
845
        }
846

847
        public OptionalDouble result() {
848
            if (cnt == 0)
1✔
849
                return OptionalDouble.empty();
1✔
850
            return OptionalDouble.of(((double) (hi + (lo < 0 ? 1 : 0)) / cnt) * 0x1.0p64 + ((double) lo) / cnt);
1✔
851
        }
852
    }
853

854
    @SuppressWarnings("serial")
855
    class CancelException extends Error {
856
        CancelException() {
857
            // Calling this constructor makes the Exception construction much
858
            // faster (like 0.3us vs 1.7us)
859
            super(null, null, false, false);
1✔
860
        }
1✔
861
    }
862

863
    class ArrayCollection extends AbstractCollection<Object> {
864
        private final Object[] arr;
865

866
        ArrayCollection(Object[] arr) {
1✔
867
            this.arr = arr;
1✔
868
        }
1✔
869

870
        @Override
871
        public Iterator<Object> iterator() {
872
            return Arrays.asList(arr).iterator();
1✔
873
        }
874

875
        @Override
876
        public int size() {
877
            return arr.length;
1✔
878
        }
879

880
        @Override
881
        public Object[] toArray() {
882
            // intentional contract violation here:
883
            // this way new ArrayList(new ArrayCollection(arr)) will not copy
884
            // array at all
885
            return arr;
1✔
886
        }
887
    }
888

889
    /**
890
     * A spliterator which may perform tail-stream optimization
891
     *
892
     * @param <T> the type of elements returned by this spliterator
893
     */
894
    interface TailSpliterator<T> extends Spliterator<T> {
895
        /**
896
         * Either advances by one element feeding it to consumer and returns
897
         * this or returns tail spliterator (this spliterator becomes invalid
898
         * and tail must be used instead) or returns null if traversal finished.
899
         * 
900
         * @param action to feed the next element into
901
         * @return tail spliterator, this or null
902
         */
903
        Spliterator<T> tryAdvanceOrTail(Consumer<? super T> action);
904

905
        /**
906
         * Traverses this spliterator and returns null if traversal is completed
907
         * or tail spliterator if it must be used for further traversal.
908
         * 
909
         * @param action to feed the elements into
910
         * @return tail spliterator or null (never returns this)
911
         */
912
        Spliterator<T> forEachOrTail(Consumer<? super T> action);
913

914
        static <T> Spliterator<T> tryAdvanceWithTail(Spliterator<T> target, Consumer<? super T> action) {
915
            while (true) {
916
                if (target instanceof TailSpliterator) {
1✔
917
                    Spliterator<T> spltr = ((TailSpliterator<T>) target).tryAdvanceOrTail(action);
1✔
918
                    if (spltr == null || spltr == target)
1✔
919
                        return spltr;
1✔
920
                    target = spltr;
1✔
921
                } else {
1✔
922
                    return target.tryAdvance(action) ? target : null;
1✔
923
                }
924
            }
925
        }
926

927
        static <T> void forEachWithTail(Spliterator<T> target, Consumer<? super T> action) {
928
            while (true) {
929
                if (target instanceof TailSpliterator) {
1✔
930
                    Spliterator<T> spltr = ((TailSpliterator<T>) target).forEachOrTail(action);
1✔
931
                    if (spltr == null)
1✔
932
                        break;
1✔
933
                    target = spltr;
1✔
934
                } else {
1✔
935
                    target.forEachRemaining(action);
1✔
936
                    break;
1✔
937
                }
938
            }
939
        }
1✔
940
    }
941

942
    abstract class CloneableSpliterator<T, S extends CloneableSpliterator<T, ?>> implements Spliterator<T>,
1✔
943
            Cloneable {
944
        @SuppressWarnings("unchecked")
945
        S doClone() {
946
            try {
947
                return (S) this.clone();
1✔
948
            } catch (CloneNotSupportedException e) {
×
949
                throw new InternalError();
×
950
            }
951
        }
952
    }
953

954
    static ObjIntConsumer<StringBuilder> joinAccumulatorInt(CharSequence delimiter) {
955
        return (sb, i) -> (sb.length() > 0 ? sb.append(delimiter) : sb).append(i);
1✔
956
    }
957

958
    static ObjLongConsumer<StringBuilder> joinAccumulatorLong(CharSequence delimiter) {
959
        return (sb, i) -> (sb.length() > 0 ? sb.append(delimiter) : sb).append(i);
1✔
960
    }
961

962
    static ObjDoubleConsumer<StringBuilder> joinAccumulatorDouble(CharSequence delimiter) {
963
        return (sb, i) -> (sb.length() > 0 ? sb.append(delimiter) : sb).append(i);
1✔
964
    }
965

966
    static <T> BinaryOperator<T> selectFirst() {
967
        return (u, v) -> u;
1✔
968
    }
969

970
    static <T> Predicate<T> alwaysTrue() {
971
        return t -> true;
1✔
972
    }
973
    
974
    static int checkLength(int a, int b) {
975
        if (a != b)
1✔
976
            throw new IllegalArgumentException("Length differs: " + a + " != " + b);
1✔
977
        return a;
1✔
978
    }
979

980
    static void rangeCheck(int arrayLength, int startInclusive, int endExclusive) {
981
        if (startInclusive > endExclusive) {
1✔
982
            throw new ArrayIndexOutOfBoundsException("startInclusive(" + startInclusive + ") > endExclusive("
1✔
983
                + endExclusive + ")");
984
        }
985
        if (startInclusive < 0) {
1✔
986
            throw new ArrayIndexOutOfBoundsException(startInclusive);
1✔
987
        }
988
        if (endExclusive > arrayLength) {
1✔
989
            throw new ArrayIndexOutOfBoundsException(endExclusive);
1✔
990
        }
991
    }
1✔
992

993
    @SuppressWarnings("unchecked")
994
    static <A> Predicate<A> finished(Collector<?, A, ?> collector) {
995
        if (collector instanceof CancellableCollector)
1✔
996
            return ((CancellableCollector<?, A, ?>) collector).finished();
1✔
997
        return null;
1✔
998
    }
999

1000
    @SuppressWarnings("unchecked")
1001
    static <T> T none() {
1002
        return (T) NONE;
1✔
1003
    }
1004

1005
    static <T> int drainTo(T[] array, Spliterator<T> spliterator) {
1006
        Box<T> box = new Box<>();
1✔
1007
        int index = 0;
1✔
1008
        while (index < array.length && spliterator.tryAdvance(box)) {
1✔
1009
            array[index++] = box.a;
1✔
1010
        }
1011
        return index;
1✔
1012
    }
1013

1014
    static int intSize(Spliterator<?> spliterator) {
1015
        long size = spliterator.getExactSizeIfKnown();
1✔
1016
        if (size < -1) {
1✔
1017
            throw new IllegalArgumentException("Spliterator violates its contract: getExactSizeIfKnown() = " + size);
1✔
1018
        }
1019
        if (size > Integer.MAX_VALUE) {
1✔
1020
            throw new OutOfMemoryError("Stream size exceeds Integer.MAX_VALUE: " + size);
1✔
1021
        }
1022
        return (int) size;
1✔
1023
    }
1024
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc