-
肥皂起泡泡
AnIterable代表提供Iterator应要求的能力。因此,要使用过滤逻辑装饰现有的可迭代对象,您必须实现 decorating Iterator。static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) { return () -> new Iterator<T>() { Iterator<T> sourceIterator = it.iterator(); T current; boolean hasCurrent; @Override public boolean hasNext() { while(!hasCurrent) { if(!sourceIterator.hasNext()) { return false; } T next = sourceIterator.next(); if(pred.test(next)) { current = next; hasCurrent = true; } } return true; } @Override public T next() { if(!hasNext()) throw new NoSuchElementException(); T next = current; current = null; hasCurrent = false; return next; } };}您可以通过它进行测试List<String> original = new ArrayList<>();Collections.addAll(original, "foo", "bar", "baz");Iterable<String> filter = select(original, s -> s.startsWith("b"));System.out.println(String.join(", ", filter));original.removeIf(s -> !s.endsWith("r"));System.out.println(String.join(", ", filter));实现这样的 , 时最大的挑战Iterator是提供两种方法hasNext和next正确的语义,而不保证调用者将如何调用它们,即你不能假设它永远不会调用hasNext()两次,也next()不会总是被调用之前hasNext()。使用 Stream API 可以更轻松地实现相同的逻辑:static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) { return () -> StreamSupport.stream(it.spliterator(), false) .filter(pred).iterator();}
-
繁星淼淼
由于 anyCollection是Iterable,只需将符合条件的项目添加到新集合中并稍后返回:static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) { Collection<T> collection = new ArrayList<>(); for (T s: it) { if (!pred.test(s)) { collection.add(s); } } return collection;}几点见解:pred.test(s)==false表达式应简化为!pred.test(s)可以使用以下方法缩短方法的全部内容java流通过这种方式:static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) { return StreamSupport.stream(it.spliterator(), false) .filter(pred) .collect(Collectors.toList());}
-
慕的地8271018
首先把你包装Iterable<T>成Stream<T>:纯Java:StreamSupport.stream(it.spliterator(), false)番石榴Streams.stream(it)流媒体StreamEx.of(it.iterator())然后按您的过滤Predicate<T>:...
stream.filter(pred.negate())
...最后返回Iterable<T>:作为lambda:return () -> stream.iterator();作为method referencereturn stream::iterator;完整示例:static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) { return StreamSupport.stream(it.spliterator(), false).filter(pred.negate())::iterator;}要么:static <T> Iterable<T> select(Iterable<T> it, Predicate<T> pred) { Stream<T> stream = stream(it.spliterator(), false); Predicate<T> negatedPred = pred.negate(); Stream<T> filteredStream = stream.filter(negatedPred); return filteredStream::iterator;}
-
猛跑小猪
我在评论中提到的 Holger 的替代解决方案如下所示:static <T> Iterable<T> select(Iterable<T> toIterate, Predicate<T> pred) { return () -> new Iterator<T>() { Iterator<T> delegate = toIterate.iterator(); T next = findNextValid(); public boolean hasNext() { return next != null; } public T next() { if (next == null) throw new NoSuchElementException(); T result = next; next = findNextValid(); return result; } private T findNextValid() { T result = null; while (result == null && delegate.hasNext()) { T candidate = delegate.next(); if (pred.test(candidate)) { result = candidate; } } return result; } };}不同之处在于,不需要额外的标记hasCurrent,它会Iterator在实际请求下一个元素之前提前。你可能认为后者是不可取的。