ç§ã¯ãæšæºã®Java 8ã¹ããªãŒã APIãæ¡åŒµããç¡æã®
StreamExã©ã€ãã©ãªãéçºããããã«æ°ããæäœãã³ã¬ã¯ã¿ãŒãããã³ã¹ããªãŒã ãœãŒã¹ãè¿œå ããŠããŸãã éåžžããã¹ãŠãé£ç¶ããŠè¿œå ããããã§ã¯ãããŸããããå¯èœæ§ã®ããåæ©èœãå
æ¬çã«æ€èšããŸãã ããšãã°ãæ°ããäžéæäœãè¿œå ãããšã次ã®ãããªçåãçããŸãã
- ããã¯æ¬åœã«äžéçãªãã®ã§ãããããã€ãŸãã端æ«æäœãå®äºãããŸã§ãœãŒã¹ã«è§ŠããŸãããïŒ
- 圌女ã¯æ ãè
ã§ããœãŒã¹ããå¿
èŠä»¥äžã®ããŒã¿ãåŒãåºãããšã¯ãããŸãããïŒ
- ç¡éã®ã¹ããªãŒã ã§åäœããŸããïŒ éãããéã®ã¡ã¢ãªãå¿
èŠã§ããïŒ
- ããã¯ããŸã䞊åããŸããïŒ
ãããã®ãã€ã³ãã®ãã€ãã¹ã¯ããã®ãããªæäœãè¿œå ãããã©ãããçå£ã«èããããŸãã æåã®ãã€ãã¹-ããã¯ããã§ã¯ãããŸããã ããšãã°ãjOOλã®ç«¶åä»ç€Ÿã«ã¯
shuffleïŒïŒæäœããããããã¯äžéã®ããã«èŠããŸãããå®éã«ã¯ãªã¹ãã®ã¹ããªãŒã å
šäœãçŽæ¥æ¶è²»ãããããæ··åããŠæ°ããã¹ããªãŒã ãäœæããŸãã ç§ã¯ãããå°éããŸããã
æ®ãã®é
ç®ã®ãã€ãã¹ã¯ããããã«éåããæšæºçãªæäœããããããããã«ããããããæå³ããããã§ã¯ãããŸããã 2çªç®ã®ã¢ã€ãã ã¯
flatMap()
ã3çªç®-
sorted()
ã4çªç®-ãã¹ãŠã®çš®é¡ã®
limit()
ããã³
takeWhile()
ïŒJDK-9ã§ïŒã«
takeWhile()
ãŸãã ããã§ããç§ã¯ãããé¿ããããšããŸãã ããããå
æ¥ãç§ã¯èªåã§ã¯äžŠååŠçãããŸããããã䜿çšæ¹æ³ã«ãã£ãŠã¯ç¡éã®ã¹ããªãŒã ã§åäœããªãå¯èœæ§ãããããšãçºèŠããŸããããããã§ãããŸãã«ãåªããŠããŸãã ããã«ãããæåéãæ°è¡ã§ãæ¢åã®äžéæäœãšãååšããªãæäœã®æãã»ãŒãã¹ãŠè¡šçŸããããšãã§ããŸãã æäœ
headTailïŒïŒãåŒã³åºããŸããã
æäœã¡ãœããã¯ã2ã€ã®é¢æ°ãã©ã¡ãŒã¿ãŒãåãå
¥ããŸãïŒä»¥äžã§ã¯ã
PECSãçç¥ããŸãïŒã
<R> StreamEx<R> headTail(BiFunction<T, StreamEx<T>, Stream<R>> mapper, Supplier<Stream<R>> supplier)
æåã®é¢æ°ã¯ãå
ã®ã¹ããªãŒã ã®æåã®èŠçŽ ãšä»ã®ãã¹ãŠã®èŠçŽ ãå«ãã¹ããªãŒã ã®2ã€ã®åŒæ°ãåããŸãã é¢æ°ã¯ããã§äœã§ãã§ããæ°ããã¹ããªãŒã ãè¿ãããšãã§ããŸããããã¯æ¬¡ã®æäœã«è»¢éãããŸãã 2çªç®ã®åŒæ°ã¯ãåŒæ°ãåãããæåã®é¢æ°ãšåãã¿ã€ãã®ã¹ããªãŒã ãè¿ãé¢æ°ã§ãã å
ã®ã¹ããªãŒã ã空ã§ããããšãå€æããå Žåã«åŒã³åºãããŸãã å®éãé¢æ°å
šäœã®1ã€ã ããåŒã³åºãããã¹ããªãŒã å
šäœã®ç«¯æ«æäœäžã«1åã ãåŒã³åºãããŸãã
å€ãã®å Žåã2çªç®ã®é¢æ°ã¯ç©ºã®ã¹ããªãŒã ã®ã¿ãè¿ãå¿
èŠããããŸãïŒå
ã®ã¹ããªãŒã ã空ã®å Žåãçµæã¯ç©ºã«ãªããŸãïŒããããã£ãŠãçç¥ã§ããŸãã
<R> StreamEx<R> headTail(BiFunction<T, StreamEx<T>, Stream<R>> mapper)
ããã§äœãã§ãããèŠãŠã¿ãŸãããã åçŽãªäœ¿çšäŸã¯æ¬¡ã®ããã«ãªããŸãã
StreamEx.of("name", "John", "Mary", "Lucy") .headTail((head, tail) -> tail.map(str -> head+": "+str)) .forEach(System.out::println);
çµè«ïŒ
name: John name: Mary name: Lucy
ããã§ã¯ãã¹ããªãŒã ã®æåã®èŠçŽ ãåé€ããããã䜿çšããŠåŸç¶ã®èŠçŽ ãšé£çµããŸãã ãããã£ãŠãæåã®è¡ã«ããããŒãããããã¹ããã¡ã€ã«ã解æã§ããŸãã ããããããã¯ããªãéå±ã§ãã ãã®æ¹æ³ã§éã¶ãšãã¯ããã«åŒ·åã§ããããšãããããŸããã ãããéããŠãJDKããã®äž»èŠãªäžéæäœãè¡šçŸããŠã¿ãŸãããã
Stream.map
ãããæäœã¯ãæå®ãããé¢æ°ãå
ã®ã¹ããªãŒã ã®ãã¹ãŠã®èŠçŽ ã«é©çšããŸãã ããã¯ãheadTailïŒïŒãéããŠã©ã®ããã«èŠãããã§ãïŒ
public static <T, R> StreamEx<R> map(StreamEx<T> input, Function<T, R> mapper) { return input.headTail((head, tail) -> map(tail, mapper).prepend(mapper.apply(head))); }
ããã§ã¯ãå¥ã®åçŽãª
ããªãã³ãæäœã䜿çšããŸããããããªãã§ã¯äœãèµ·ãããŸããã ããã¯ã2ã€ã®ã¹ããªãŒã ã®é£çµã«é¢ãããããã¯ã®ããªãšãŒã·ã§ã³ã§ãïŒStream.concatã¯æšæºAPIã«ãããŸãïŒã ããã§ã¯ãæ«å°ŸãåŒã³åºããŠãããé¢æ°ãã¹ããªãŒã ã®å
é ã«ããheadèŠçŽ ã«é©çšããçµæãè¿œå ããŸãã
ããã¯ååž°ã«äŒŒãŠããŸããã誰ããååž°ãã¹ã¿ãã¯ãæ¶è²»ããŠããããšãç¥ã£ãŠããŸãã é¢æ°åããã°ã©ãã³ã°èšèªã§
ã¯ãæ«å°Ÿååž°ã®æé©åã«ãã£ãŠç¯çŽãããå ŽåããããŸãããJavaã§ã¯ããã§ã¯ãªããäºæãããŠããŸããã ãã ãããã®å Žåãããã¯å®å
šãªååž°ã§ã¯ãããŸãããèªåèªèº«ã®äžã§mapã¡ãœãããåŒã³åºãã®ã§ã¯ãªããåŸã§åŒã³åºãããé¢æ°ãäœæããã ãã§ãã ãã®å Žåãåã
ã®
headTail()
ãžã®å€æŽãã¹ããªãŒã ã®å
é ã®ã¿ã«åœ±é¿ããããŒã«ã¯å€æŽãããªããŸãŸã§ããã°ãåŒã³åºãã®æ·±ããå¶åŸ¡ã§ããããšãå€æããŸããã ãã®æ©èœããããŒã«ã¹ããªãŒã ã®æé©åããšã¯ããŸãèããŠããŸããã§ããã äžéæäœ
prepend
ïŒã¹ããªãŒã ã®å
é ã«äœããè¿œå ããïŒã
mapFirst
ïŒæ®ãã®éšåã«è§Šããããšãªãã¹ããªãŒã ã®æåã®èŠçŽ ãå€æŽããïŒãããã³
headTail
èªäœãš
headTail
ãŸãã ååãšããŠãæšæºã®skipããã³dropWhileïŒJDK-9ã䜿çšïŒã«æ¡åŒµã§ããŸãããç§ã®ã©ã€ãã©ãªã¯æšæºæäœãå
ã®Stream APIãšå®å
šã«äºææ§ãããããšãçŽæããŠãããããã§åŸ®åŠãªéããçããŸãã
äœããã®æ¹æ³ã§ãäžèšã®ãããæäœã¯ãäžå®ãµã€ãºããã倧ããã¹ã¿ãã¯ãŸãã¯ã¡ã¢ãªãæ¶è²»ãããä»»æã®é·ãã®ã¹ããªãŒã ã«ãŸã£ããé©çšã§ããŸãã ä»ã®æäœãèŠãŠã¿ãŸãããã
Stream.limit
ã¹ããªãŒã ãæå®ãããé·ãã«å¶éããŸãã ããã1ã€ã®èŠçŽ ã«å¶éããå Žåã¯ãåçŽã«ãããããã¹ããªãŒã ãäœæããŸããããã§ãªãå Žåã¯ãå¶éãæžãããŠããŒã«ãåŒã³åºããŸãïŒãã³ãã«n <= 0-èªè
ã®ããã®æŒç¿ïŒã
public static <T> StreamEx<T> limit(StreamEx<T> input, int n) { return input.headTail((head, tail) -> n > 1 ? limit(tail, n - 1).prepend(head) : Stream.of(head)); }
æåã¯å°ãéãæ¹æ³ã§æžããŸããïŒflatMapåŒæ°ã®ããã«ãheadTailåŒæ°ã¯ç©ºã®ã¹ããªãŒã ã®ä»£ããã«nullãè¿ãããšãã§ããŸãïŒïŒ
public static <T> StreamEx<T> limit(StreamEx<T> input, int n) { return input.headTail((head, tail) -> n > 0 ? limit(tail, n - 1).prepend(head) : null); }
ãã ãããã®å®è£
ã«ã¯æ¬ ç¹ããããŸãããœãŒã¹ããå¿
èŠä»¥äžã«1ã€ã®èŠçŽ ãèæ
®ããŸãïŒn = 0ã®å ŽåãheadåŒæ°ãèªã¿åãããŸããã䜿çšãããŸããïŒã ããã¯é倧ãªå ŽåããããŸãã ããšãã°ããã®ãããªã³ãŒãã¯æ©èœããã¯ãã§ãã
limit(StreamEx.of(new Random().ints(0, 1000).boxed().distinct()), 1000).forEach(System.out::println);
0ãã999ãŸã§ã®ä¹±æ°ã®ç¡éã®ã¹ããªãŒã ãããäžæã®ä¹±æ°ãéžæããŸãã 1000åã®ãŠããŒã¯ãªçªå·ããããŸããã1001åã¯ãããŸããããã®ããããœãŒã¹ãã1001çªç®ã®çªå·ãååŸããããšãããšããã¹ãŠãããªãŒãºããŸãã
Stream.skip
æåã®nåã®èŠçŽ ãæšãŠãŸãã n = 0ã®å Žåãããããæ¥çãããŸãŸããŒã«ãè¿ããŸãããã以å€ã®å Žåã¯ãåŒæ°ãæžãããŠåŒã³åºããŸãã
static <T> StreamEx<T> skip(StreamEx<T> input, int n) { return input.headTail((head, tail) -> n > 0 ? skip(tail, n - 1) : tail.prepend(head)); }
Stream.flatMap
ã¹ããªãŒã äžã®åèŠçŽ ã衚瀺ãããããããå
±éã®ã¹ããªãŒã ãäœæããŸãã ãã®å Žåãå®è£
ã¯ããããšåãã§ãã
public static <T, R> StreamEx<R> flatMap(StreamEx<T> input, Function<T, Stream<R>> mapper) { return input.headTail((head, tail) -> flatMap(tail, mapper).prepend(mapper.apply(head))); }
ããã§ã®å¯äžã®éãã¯ãã¹ããªãŒã ãåãå
¥ããå¥ã®
ããªãã³ãã䜿çšãããããšã§ãïŒå®éãæåã®ããªãã³ãã¯ãã®ç¹æ®ãªã±ãŒã¹ã§ãïŒã
Stream.peek
ã¹ããªãŒã ã®åèŠçŽ ã«å¯ŸããŠè¿œå ã®ã¢ã¯ã·ã§ã³ãå®è¡ããã¹ããªãŒã ããã®ãŸãŸè¿ããŸãã ã¢ã¯ã·ã§ã³ãå®è¡ããé ã尻尟ã«æ¥çããŸãã
public static <T> StreamEx<T> peek(StreamEx<T> input, Consumer<T> consumer) { return input.headTail((head, tail) -> { consumer.accept(head); return peek(tail, consumer).prepend(head); }); }
Stream.filter
è¿°éšãæºããèŠçŽ ãæ®ããŸãã è¿°éšãæºããããŠããå Žåã«ã®ã¿é ãæ¥çããŸãã
public static <T> StreamEx<T> filter(StreamEx<T> input, Predicate<T> predicate) { return input.<T> headTail((head, tail) -> predicate.test(head) ? filter(tail, predicate).prepend(head) : filter(tail, predicate)); }
Stream.distinct
ãŠããŒã¯ãªã¢ã€ãã ãæ®ãã æããã«è¿œå ã®ã¡ã¢ãªãå¿
èŠã«ãªããŸãã åçŽãªå®è£
ã§ã¯ããã£ã«ã¿ãŒïŒæšæºãŸãã¯äžèšã§å®£èšããããã®ïŒã䜿çšããŸãã
public static <T> StreamEx<T> distinct(StreamEx<T> input) { return input.headTail((head, tail) -> distinct(tail.filter(n -> !Objects.equals(head, n))).prepend(head)); }
ãããããã®ãããªã³ãŒãã¯äŸç¶ãšããŠã¹ã¿ãã¯ã䜿ãæãããããŒã«ã¹ããªãŒã ã®æé©åã¯ãããŸããã ããã«ãåèŠçŽ ã¯ãã£ã«ã¿ãŒãã§ãŒã³ã«ãã£ãŠç·åœ¢ã«ãã§ãã¯ãããŸãããæé©åããããšæããŸãã ãããè¡ãã«ã¯ãHashSetãã©ã¡ãŒã¿ãŒãä¿æããŸãã
private static <T> StreamEx<T> distinct(StreamEx<T> input, Set<T> observed) { return input.headTail((head, tail) -> observed.add(head) ? distinct(tail, observed).prepend(head) : distinct(tail, observed)); }
èŠçŽ ãæ¢ã«ã»ããã«å«ãŸããŠããå Žåã
Set.add
ã¯
false
è¿ãããšãå¿ããªãã§ãã ããã ãã®å Žåãé ãåºããªãã§ãã ããã ãã®ãããªå®è£
ã¯ã¹ã¿ãã¯ã䜿ãæããããæšæºã®ã¡ã¢ãªãããå£ããŸããã ããã§ã¯ãå®è¡ããã¡ãœãããè¿œå ãã䟡å€ããããŸãïŒååž°é¢æ°ã§ã¯ãå®è¡ããããã«å¥ã®ãããªãã¯ã¡ãœãããå¿
èŠã«ãªãããšããããããŸãïŒã
public static <T> StreamEx<T> distinct(StreamEx<T> input) { return distinct(input, new HashSet<>()); }
Stream.sorted
ã¹ããªãŒã ã䞊ã¹æ¿ããŸãã æäœã¯ç¹å¥ã§ãããœãŒã¹ãå®å
šã«èªã¿åããããŸã§ãçµæã«äœãäžããããšã¯ã§ããŸããã ãã¹ãŠããããã¡ãªã³ã°ããå¿
èŠãããïŒããšãã°ã
ArrayList
ïŒãããã§ã¯åããŠ2çªç®ã®åŒæ°
headTail
ã䜿çšããŸãã
public static <T> StreamEx<T> sorted(StreamEx<T> input) { return sorted(input, new ArrayList<>()); } private static <T> StreamEx<T> sorted(StreamEx<T> input, List<T> buf) { return input.headTail((head, tail) -> { buf.add(head); return sorted(tail, buf); }, () -> { buf.sort(null); return buf.stream(); }); }
ãœãŒã¹ã¹ããªãŒã å
šäœãçµäºãããããããã¡ã䞊ã¹æ¿ããããããã¹ããªãŒã ãè¿ããŸãã ãã®ãããª
sorted
ã¯æšæºã®ãã®ãšåæ§ã«æ©èœããäžèšã®
shuffle
ãããåªããŠããããšã«æ³šæããŠãã ããã ããšãã°ã2ã€ã®ãœãŒããããã¹ããªãŒã ãé£çµãããšãæåã®ã¹ããªãŒã ãå®å
šã«èªã¿åããŸã§ã2çªç®ã®ã¹ããªãŒã ã¯ãœãŒããããŸããã ã¡ãªã¿ã«ã
buf.sort(null)
ã
Collections.shuffle(buf)
ã«çœ®ãæããããšã§ãããªããš
shuffle
ã¯ã»ãŒæ£åžžã«åäœããŸãã
Collections.reverse(buf)
ã䜿çšãããšãã¹ããªãŒã ãå転ã§ããŸãã
JDK-9ã§ã¯ããããŸã§ã«2ã€ã®æ°ããäžéæäœãè¿œå ãããŠããŸãã ãŸããããããå®çŸããŸãã
Stream.takeWhile
è¿°éšãfalseãè¿ãããããã«ã¹ããªãŒã ãããªãã³ã°ããŸãã å¶éã®ããã«èŠããŸãïŒ
public static <T> StreamEx<T> takeWhile(StreamEx<T> input, Predicate<T> predicate) { return input.headTail((head, tail) -> predicate.test(head) ? takeWhile(tail, predicate).prepend(head) : null); }
Stream.dropWhile
è¿°éšã
false
è¿ããŸã§ãã¹ããªãŒã ããèŠçŽ ãã¹ããŒã
false
ã
skip
䌌ãŠããŸãïŒ
public static <T> StreamEx<T> dropWhile(StreamEx<T> input, Predicate<T> predicate) { return input.headTail((head, tail) -> predicate.test(head) ? dropWhile(tail, predicate) : tail.prepend(head)); }
ããŠãè»èŒªã®åçºæã¯éå±ã§ãã Stream APIã«ã¯ãªãæ°ããæäœãå®è£
ããŠã¿ãŸãããã
é¡
ã³ã³ãã³ããã¹ããªãŒã ã®æåŸã«éé ã§è¿œå ããŸãïŒ1ã2ã3ããã®ã¹ããªãŒã ã1ã2ã3ã3ã2ã1ã«ãªããŸãïŒã ç°¡åã«å®è¡ã§ããŸãããããŒã«ã®æé©åã¯è¡ãããŸããã
public static <T> StreamEx<T> mirror(StreamEx<T> input) { return input.headTail((head, tail) -> mirror(tail).append(head).prepend(head)); }
æ«å°Ÿããããããã¡ãå¿
èŠã§ãã
public static <T> StreamEx<T> mirror(StreamEx<T> input) { return mirror(input, new ArrayDeque<>()); } private static <T> StreamEx<T> mirror(StreamEx<T> input, Deque<T> buf) { return input.headTail((head, tail) -> { buf.addFirst(head); return mirror(tail, buf).prepend(head); }, buf::stream); }
äž¡æ¹ã®å®è£
ã¯ãå¿
èŠä»¥äžã®ãã®ãåããŸããïŒ
mirror(StreamEx.of(1,2,3,4,5)).limit(3)
ã¯åå°ç¹ã«å°éããããœãŒã¹ãã3ã€ã®èŠçŽ ã®ã¿ãæžç®ããŸãã
scanLeft
ã¹ããªãŒã ãé 次å€æŽããç¹å®ã®æäœãå®è¡ããŸãã ããšãã°ã
scanLeft(StreamEx.of(1,2,3,4,5), Integer::sum)
ã¯èŠçŽ ãé£ç¶ããŠåèšããã¹ããªãŒã
scanLeft(StreamEx.of(1,2,3,4,5), Integer::sum)
ãäœæããå¿
èŠããããŸãã
public static <T> StreamEx<T> scanLeft(StreamEx<T> input, BinaryOperator<T> operator) { return input.headTail((head, tail) -> scanLeft(tail.mapFirst(cur -> operator.apply(head, cur)), operator).prepend(head)); }
ããã§ã¯ããã§ã«
StreamExã«ããmapFirstã¡ãœããã䜿çšããŸããã ãããããããªããã°ãååž°ããªããŠãç°¡åã«æžãããšãã§ããŸãã
public static <T> StreamEx<T> mapFirst(StreamEx<T> input, UnaryOperator<T> operator) { return input.headTail((head, tail) -> tail.prepend(operator.apply(head))); }
ãããã®å ŽåããmapFirstãšæ¢åã®ããŒã«ã®äž¡æ¹ã§ããŒã«ãæé©åãããŸãã
takeWhileClosed
ååã¯ããŸãæåããªããããããŸããã å Žåã«ãã£ãŠã¯ãè¿°èªãæºããèŠçŽ ã ãã§ãªããããã«éåããæåã®èŠçŽ ãå«ãŸããããã«ã
takeWhile
ãå€æŽããããšããããŸãã æ¢åã®æäœãšéåžžã®
takeWhile
ãä»ããŠãããè¡šçŸããã®ã¯æ®éã§ã¯ãããŸããã
headTail
ã
headTail
ãšç°¡åã§ãã
public static <T> StreamEx<T> takeWhileClosed(StreamEx<T> input, Predicate<T> predicate) { return input.headTail((head, tail) -> predicate.test(head) ? takeWhileClosed(tail, predicate).prepend(head) : Stream.of(head)); }
æ¯å
æåããå§ããŠãæå®ãããééïŒããšãã°ã10åããšïŒã§ã¹ããªãŒã ããèŠçŽ ãååŸããŸãã ããã§
skip
æäœãšçµã¿åããããšäŸ¿å©ã§ãããæšæºã®
skip
ã¯ããŒã«ãæé©åãããªãããããªãŒããŒã©ã€ãããã
skip
ã䜿çšããŸãã
public static <T> StreamEx<T> every(StreamEx<T> input, int n) { return input.headTail((head, tail) -> every(skip(tail, n - 1), n).prepend(head)); }
ã«ããã«
æå®ãããé¢æ°ããããã«é©çšããããšã«ãããã¹ããªãŒã ãèŠçŽ ã®äºãã«çŽ ãªãã¢ã«åå²ããŸãïŒèŠçŽ ã®æ°ãå¥æ°ã®å ŽåãæåŸã®èŠçŽ ãã¹ããŒããŸãïŒã ããã§ã¯ã
headTail
2ååŒã³åºããšäŸ¿å©ã§ãã
public static <T, R> StreamEx<R> couples(StreamEx<T> input, BiFunction<T, T, R> mapper) { return input.headTail((left, tail1) -> tail1.headTail((right, tail2) -> couples(tail2, mapper).prepend(mapper.apply(left, right)))); }
pairMap
亀差ãããã¢ã§ãåãããšãå¿
èŠã§ããïŒ ç°¡åã§ããååž°åŒã³åºãäžã«é©åãªèŠçŽ ãã¹ããªãŒã ã«è¿ãã ãã§ãã
public static <T, R> StreamEx<R> pairMap(StreamEx<T> input, BiFunction<T, T, R> mapper) { return input.headTail((left, tail1) -> tail1.headTail((right, tail2) -> pairMap(tail2.prepend(right), mapper).prepend(mapper.apply(left, right)))); }
ãã®ãããªæäœã¯æ¢ã«StreamExã«ãããç§
ã¯ããã«ã€ããŠ
æžããŸããã ãã¡ããã
headTail()
ã«ããå®è£
ãšã¯ç°ãªããéåžžã¯äžŠååãããŸãã
ããã
ããŠããã¢ã§ãç§ã¯ããããŸãã ãããŠãã¹ããªãŒã ãåºå®é·ã®æçã«ïŒãªã¹ãã®åœ¢åŒã§ïŒåå²ããæåŸã«æŽæ°ä»¥å€ã®æçã倱ããããªãå Žåã¯ã©ãã§ããããïŒ ããšãã°ã
batches(StreamEx(1,2,3,4,5,6,7), 3)
ã¯ããªã¹ã
[1,2,3], [4,5,6], [7]
ããã¹ããªãŒã ãäœæããå¿
èŠããããŸãã äžéãããã¡ãå«ãåŒæ°ã¯ããã§åœ¹ç«ã¡ãŸãïŒ
public static <T> StreamEx<List<T>> batches(StreamEx<T> input, int size) { return batches(input, size, Collections.emptyList()); } private static <T> StreamEx<List<T>> batches(StreamEx<T> input, int size, List<T> cur) { return input.headTail((head, tail) -> cur.size() >= size ? batches(tail, size, Collections.singletonList(head)).prepend(cur)
ãœãŒã¹ã䜿ãæããããå ŽåãæåŸã«èç©ããããããã¡ã
() -> Stream.of(cur)
ã䜿çšããŠçµæã«æ»ããããŒã«ã倱ãããªãããã«ããŸãã ããã§ã¯ãå®è£
StreamEx.of(cur).append(head).toList()
çŸããã®ããã«ã
StreamEx.of(cur).append(head).toList()
ã䜿çšããŠæ°ãããªã¹ããäœæãããã³ã«ãæ¢åã®ãªã¹ããå€æŽããŸããã ãã ããããã©ãŒãã³ã¹ãéèŠãªå Žåã¯ãå€æŽå¯èœãªãªã¹ããç°¡åã«æ¿å
¥ã§ããŸãã
withIndices
ã¹ããªãŒã å
ã®èŠçŽ ã®ã€ã³ããã¯ã¹ãç¥ãå¿
èŠããããŸããïŒ ãããå¯èœã§ãã ã€ã³ããã¯ã¹ãšèŠçŽ ã®ãã¢ã®ãããªç¹å¥ãªåãéå§ããªãããã«ã
BiFunction<Integer, T, R>
åã®æœè±¡é¢æ°ã䜿çšããŸããããã¯ãã€ã³ããã¯ã¹ãšèŠçŽ ã§å¿
èŠãªåŠçãå®è¡ã§ããŸãã
public static <T, R> StreamEx<R> withIndices(StreamEx<T> input, BiFunction<Integer, T, R> mapper) { return withIndices(input, 0, mapper); } private static <T, R> StreamEx<R> withIndices(StreamEx<T> input, int idx, BiFunction<Integer, T, R> mapper) { return input.headTail((head, tail) -> withIndices(tail, idx + 1, mapper).prepend(mapper.apply(idx, head))); }
æ¯é
è
ãããšããŸããã¯ãªã¿ã¹ã¯ïŒæå®ãããèŠçŽ ããæ¯é
ãããç¹å®ã®èŠçŽ ã«ç¶ãèŠçŽ ãã¹ããŒããŸãã åªäœæ§ã¯ã2ã€ã®èŠçŽ ããè¿°èªãå®çŸ©ããŸãã ããšãã°ã
dominators(numbers, (a, b) -> a >= b)
ã¯ãå
ã®æ°å€ã®ãµãã»ãããå¢ãããŸãã å®è£
ã¯ãã¹ãŠã«äŒŒãŠããŸãããdropWhileãã¹ããããã代ããã«äœ¿çšãããŸãïŒ
public static <T> StreamEx<T> dominators(StreamEx<T> input, BiPredicate<T, T> isDominator) { return input.headTail((head, tail) -> dominators(dropWhile(tail, e -> isDominator.test(head, e)), isDominator) .prepend(head)); }
appendReduction
ã¹ããªãŒã ã®æåŸã«å¥ã®èŠçŽ ãè¿œå ããŸã-äžããããæäœã§ã®åæžã®çµæã ããšãã°ã
appendReduction(numbers, 0, Integer::sum)
ããã®èŠçŽ ã®åèšãæ°å€ã®ã¹ããªãŒã ã«è¿œå ããŸãã
public static <T> StreamEx<T> appendReduction(StreamEx<T> input, T identity, BinaryOperator<T> op) { return input.headTail((head, tail) -> appendReduction(tail, op.apply(identity, head), op).prepend(head), () -> Stream.of(identity)); }
ãã€ãã®ããã«ããã¹ãŠãæ zyã§ãããããŒã«ãæé©åãããŠããŸãã
çŽ æ°
ããããåŠç¿ã¿ã¹ã¯ã ãšã©ãã¹ããã¹ã®ãµãããäœæããŸãããã§ã«èŠããã®ã«åå²ãããŠããçŽ æ°ãã¹ããŒããçŽ æ°ã®æ zyãªã¹ããªãŒã ïŒ
public static StreamEx<Integer> sieve(StreamEx<Integer> input) { return sieve(StreamEx.iterate(2, x -> x+1)); } private static StreamEx<Integer> sieve(StreamEx<Integer> input) { return input.headTail((head, tail) -> sieve(tail.filter(n -> n % head != 0)).prepend(head)); }
ããã§ã¯ãé¢æ°åèšèªã®åæ§ã®ãã®ããã¡ããæé©åãããŠããŸããããããŒã«ã®æé©åã¯ååŸãããŸããã ããããããã¯ç°¡åã«èŠããŸãã æšæºèšå®ã§ã¯ãJVMã¯StackOverflowErrorã§ã¯ã©ãã·ã¥ãããŸã§ãæ倧200,000以äžã®çŽ æ°ãçºè¡ããŸãã
ä»ã®äŸ¿å©ãªæäœãèãåºãããšãã§ããŸãã ããšãã°ãã¹ããªãŒã ã®å
容ãæå®ãããåæ°ã ãã«ãŒãã§ç¹°ãè¿ããŸãã ãŸãã¯ã2ã€ã®ç°ãªããã£ã«ã¿ãŒã§ãã£ã«ã¿ãŒåŠçããŠã¹ããªãŒã ãè€è£œããŸãïŒåæã«ã2çªç®ã®ãã£ã«ã¿ãŒãééããªãã£ãã¡ã¢ãªã«ä¿åããªãã§ãã ããïŒã å®è¡äžã®ãŠã£ã³ããŠãäœæã§ããŸãïŒãããã«äŒŒãŠããŸãããéè€ããŠããŸãïŒã å®éãäœãæãã€ãããšããŠãããããheadTailã§éåžžã«çæéã§å®è£
ããããšãã§ããŸããïŒç§ã®ãã¹ãã¯
ãã¡ãã§ã ïŒã ãããã«ãããç§ã«ãšã£ãŠãheadTailã¯
Iterator
ã
Spliterator
æžããããæããã«çãç解ãããã
Spliterator
ã ç§ãç解ããŠããããã«ãé¢æ°åããã°ã©ãã³ã°ã®äžçã§ã¯ããã®ãããªããšã¯åœããåã§ãã Javaã§ãããå¯èœã§ããããšã¯çŽ æŽãããããšã§ãã
åãã§ããã°ã©ã ïŒ