JENA-1809: Improvements to Iter
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/optimizer/reorder/ReorderTransformationSubstitution.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/optimizer/reorder/ReorderTransformationSubstitution.java
index decf1cd..d05f361 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/optimizer/reorder/ReorderTransformationSubstitution.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/optimizer/reorder/ReorderTransformationSubstitution.java
@@ -22,7 +22,8 @@
import java.util.ArrayList ;
import java.util.List ;
-import org.apache.jena.atlas.iterator.AccString ;
+import java.util.stream.Collectors;
+
import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.atlas.lib.StrUtils ;
import org.apache.jena.graph.Node ;
@@ -74,13 +75,8 @@
return components ;
}
- private AccString<PatternTriple> formatter() {
- return new AccString<PatternTriple>() {
- @Override
- protected String toString(PatternTriple pt) {
- return "(" + printAbbrev(pt.toString()) + ")" ;
- }
- } ;
+ private String formatted(List<PatternTriple> components) {
+ return components.stream().map(c->"(" + printAbbrev(c.toString()) + ")").collect(Collectors.joining(" "));
}
protected ReorderProc reorder(List<Triple> triples, List<PatternTriple> components) {
@@ -89,7 +85,7 @@
int indexes[] = new int[N] ;
if ( DEBUG )
- log.debug("Reorder: " + Iter.asString(components, formatter())) ;
+ log.debug("Reorder: " + formatted(components));
int idx = 0 ;
for ( ; idx < numReorder ; idx++ ) {
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java
index 91ba3a8..3a5ee08 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java
@@ -57,7 +57,7 @@
try {
UpdateSink sink = uProc.getUpdateSink();
- Iter.sendToSink(request, sink); // Will call close on sink if there are no exceptions
+ Iter.sendToSink(request.iterator(), sink); // Will call close on sink if there are no exceptions
} finally {
uProc.finishRequest() ;
}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java
index 7672f71..cf38e50 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java
@@ -176,7 +176,7 @@
@Override
public void visit(UpdateDataInsert update)
{
- Iter.sendToSink(update.getQuads(), createInsertDataSink()); // Iter.sendToSink() will call close() on the sink
+ Iter.sendToSink(update.getQuads().iterator(), createInsertDataSink()); // Iter.sendToSink() will call close() on the sink
}
@Override
@@ -190,7 +190,7 @@
@Override
public void visit(UpdateDataDelete update)
{
- Iter.sendToSink(update.getQuads(), createDeleteDataSink()); // Iter.sendToSink() will call close() on the sink
+ Iter.sendToSink(update.getQuads().iterator(), createDeleteDataSink()); // Iter.sendToSink() will call close() on the sink
}
// Prettier later.
@@ -205,7 +205,7 @@
SinkQuadBracedOutput sink = new SinkQuadBracedOutput(out, sCxt);
sink.open();
- Iter.sendToSink(quads, sink);
+ Iter.sendToSink(quads.iterator(), sink);
}
protected void output(Node node)
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/serializer/TriplesListBlock.java b/jena-arq/src/main/java/org/apache/jena/sparql/serializer/TriplesListBlock.java
index 37671b8..df33ea4 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/serializer/TriplesListBlock.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/serializer/TriplesListBlock.java
@@ -37,7 +37,10 @@
@Override
public String toString() {
- return Iter.asString(listElementsMap.keySet(), ", ") + "\n" + "{"+ Iter.asString(triplesInLists.iterator(), "\n")+"}";
-
+
+ return Iter.asString(listElementsMap.keySet().iterator(), ", ")
+ + "\n" + "{"+
+ Iter.asString(triplesInLists.iterator(), "\n")
+ +"}";
}
}
\ No newline at end of file
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/StringUtils.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/StringUtils.java
index 154c1fc..dc40a3e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/StringUtils.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/StringUtils.java
@@ -72,7 +72,7 @@
/** Abbreviate, crudely, URI in strings, leaving only their last component. */
public static <T> String printAbbrevList(List<T> objs)
{
- String x = Iter.asString(objs, "\n") ;
+ String x = Iter.asString(objs.iterator(), "\n") ;
return printAbbrev(x) ;
}
}
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryBasic.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryBasic.java
index 7401f70..25d5fb2 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryBasic.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryBasic.java
@@ -19,8 +19,8 @@
package org.apache.jena.sparql.core.mem;
import static java.lang.System.err ;
+import static org.apache.jena.atlas.iterator.Iter.anyMatch ;
import static org.apache.jena.atlas.iterator.Iter.iter ;
-import static org.apache.jena.atlas.iterator.Iter.some ;
import static org.apache.jena.graph.Node.ANY ;
import static org.apache.jena.graph.NodeFactory.createBlankNode ;
import static org.apache.jena.graph.NodeFactory.createURI ;
@@ -58,7 +58,7 @@
final Triple triple = parseTriple("(:s :p :o)");
dsg.getDefaultGraph().add(triple);
final Iterator<Triple> iter = dsg.getDefaultGraph().find(null, p, null) ;
- assertTrue(some(iter, triple::equals));
+ assertTrue(anyMatch(iter, triple::equals));
final Node p1 = parseNode(":p1") ;
@@ -67,7 +67,7 @@
final Iterator<Quad> iter2 = dsg.find(null, null, p1, null) ;
- assertTrue(some(iter2, quad::equals));
+ assertTrue(anyMatch(iter2, quad::equals));
Iter.print(err,iter2);
}
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/iterator/AccString.java b/jena-base/src/main/java/org/apache/jena/atlas/iterator/AccString.java
deleted file mode 100644
index 7df3486..0000000
--- a/jena-base/src/main/java/org/apache/jena/atlas/iterator/AccString.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jena.atlas.iterator;
-
-public class AccString<T> implements Accumulate<T, String>
-{
- StringBuilder buffer = null ;
- private String sep ;
- private boolean first = true ;
-
- // Fresh StringBuilder
- public AccString(String sep) { this.sep = sep ; }
- public AccString() { this(" ") ; }
-
- @Override
- public void accumulate(T item)
- {
- if ( ! first )
- buffer.append(sep) ;
- if ( item != null )
- buffer.append(toString(item)) ;
- else
- buffer.append("<null>") ;
- first = false ;
- }
-
- /** Make into a string */
- protected String toString(T item)
- {
- return item.toString() ;
- }
-
- @Override
- public String get()
- {
- return buffer.toString() ;
- }
-
- @Override
- public void start()
- {
- // Resets on each use.
- buffer = new StringBuilder() ;
- first = true ;
- }
-
- @Override
- public void finish() {}
-
-}
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/iterator/Accumulate.java b/jena-base/src/main/java/org/apache/jena/atlas/iterator/Accumulate.java
deleted file mode 100644
index 2eef4fa..0000000
--- a/jena-base/src/main/java/org/apache/jena/atlas/iterator/Accumulate.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jena.atlas.iterator;
-
-public interface Accumulate <T, R>
-{
- public void start() ;
- public void accumulate(T item) ;
- public void finish();
- public R get() ;
-}
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/iterator/Iter.java b/jena-base/src/main/java/org/apache/jena/atlas/iterator/Iter.java
index 17da134..97661fa 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/iterator/Iter.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/iterator/Iter.java
@@ -20,9 +20,9 @@
import java.io.PrintStream ;
import java.util.* ;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
+import java.util.function.*;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
import java.util.stream.Stream ;
import java.util.stream.StreamSupport ;
@@ -53,6 +53,12 @@
* @param <T> the type of element over which an instance of {@code Iter} iterates,
*/
public class Iter<T> implements Iterator<T> {
+
+ /** Shorter form of "forEachRemaining" */
+ public static <T> void forEach(Iterator<T> iter, Consumer<T> action) {
+ iter.forEachRemaining(action);
+ }
+
// IteratorSlotted needed? IteratorPeek
// IteratorSlotted.inspect
@@ -82,21 +88,12 @@
/** Collect an iterator into a set. */
public static <T> Set<T> toSet(Iterator<? extends T> stream) {
- Set<T> acc = new HashSet<>() ;
- collect(acc, stream) ;
- return acc ;
+ return collect(stream, Collectors.toSet());
}
/** Collect an iterator into a list. */
public static <T> List<T> toList(Iterator<? extends T> stream) {
- List<T> acc = new ArrayList<>() ;
- collect(acc, stream) ;
- return acc ;
- }
-
- /** Collect an iterator. */
- private static <T> void collect(Collection<T> acc, Iterator<? extends T> stream) {
- stream.forEachRemaining((x)->acc.add(x)) ;
+ return collect(stream, Collectors.toList());
}
/**
@@ -108,61 +105,95 @@
return x.iterator() ;
}
+ // Note fold-left and fold-right
+ // http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29
+
+ // This reduce is a kind of fold-left (take first element, apply to rest of list)
+ // and can deal with lists of zero elements.
+
// -- Operations on iterators.
- public interface Folder<X, Y> {
- Y eval(Y acc, X arg) ;
- }
+ @FunctionalInterface
+ public interface Folder<X, Y> extends BiFunction<Y,X,Y> {}
- public static <T, R> R foldLeft(Iterable<? extends T> stream, Folder<T, R> function, R value) {
- return foldLeft(stream.iterator(), function, value) ;
- }
-
- public static <T, R> R foldLeft(Iterator<? extends T> stream, Folder<T, R> function, R value) {
+ public static <T, R> R foldLeft(Iterator<? extends T> stream, R value, Folder<T, R> function) {
// Tail recursion, unwound
for (; stream.hasNext();) {
T item = stream.next() ;
- value = function.eval(value, item) ;
+ value = function.apply(value, item) ;
}
return value ;
}
- public static <T, R> R foldRight(Iterable<? extends T> stream, Folder<T, R> function, R value) {
- return foldRight(stream.iterator(), function, value) ;
- }
-
- public static <T, R> R foldRight(Iterator<? extends T> stream, Folder<T, R> function, R value) {
+ public static <T, R> R foldRight(Iterator<? extends T> stream, R value, Folder<T, R> function) {
// Recursive.
if ( !stream.hasNext() )
return value ;
T item = stream.next() ;
- return function.eval(foldRight(stream, function, value), item) ;
+ return function.apply(foldRight(stream, value, function), item) ;
}
- // Note fold-left and fold-right
- // http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29
-
- // This reduce is fold-left (take first element, apply to rest of list)
- // which copes with infinite lists.
- // Fold-left starts by combining the first element, then moves on.
-
- /** Reduce by aggregator.
- * This reduce is fold-left (take first element, apply to rest of list)
- */
- public static <T, R> R reduce(Iterable<? extends T> stream, Accumulate<T, R> aggregator) {
- return reduce(stream.iterator(), aggregator) ;
+ public static <T> Optional<T> reduce(Iterator<T> iter, BinaryOperator<T> accumulator) {
+ T r = reduce(iter, null, accumulator);
+ return Optional.ofNullable(r);
}
- /** Reduce by aggregator.
- * This reduce is fold-left (take first element, apply to rest of list)
- */
- public static <T, R> R reduce(Iterator<? extends T> stream, Accumulate<T, R> aggregator) {
- aggregator.start() ;
- for (; stream.hasNext();) {
- T item = stream.next() ;
- aggregator.accumulate(item) ;
+
+ public static <T> T reduce(Iterator<T> iter, T identity, BinaryOperator<T> accumulator) {
+ T result = identity;
+ while(iter.hasNext()) {
+ T elt = iter.next();
+ result = (result == null) ? elt : accumulator.apply(result, elt);
}
- aggregator.finish() ;
- return aggregator.get() ;
+ return result;
+ }
+
+ // ---- min and max
+ public static <T> Optional<T> min(Iterator<T> iter, Comparator<T> comparator) {
+ T x = null;
+ while(iter.hasNext()) {
+ T elt = iter.next();
+ if ( x == null )
+ x = elt;
+ else {
+ int cmp = comparator.compare(x, elt);
+ if ( cmp > 0 )
+ x = elt;
+ }
+ }
+ return Optional.ofNullable(x);
+ }
+
+ public static <T> Optional<T> max(Iterator<T> iter, Comparator<T> comparator) {
+ // Or min(iter, comparator.reversed())
+ T x = null;
+ while(iter.hasNext()) {
+ T elt = iter.next();
+ if ( x == null )
+ x = elt;
+ else {
+ int cmp = comparator.compare(x, elt);
+ if ( cmp < 0 )
+ x = elt;
+ }
+ }
+ return Optional.ofNullable(x);
+ }
+
+ // ---- collect
+ /** See {@link Stream#collect(Supplier, BiConsumer, BiConsumer)}, except without the {@code BiConsumer<R, R> combiner} */
+ public static <T,R> R collect(Iterator<T> iter, Supplier<R> supplier, BiConsumer<R, ? super T> accumulator) {
+ R result = supplier.get();
+ while(iter.hasNext()) {
+ T elt = iter.next();
+ accumulator.accept(result, elt);
+ }
+ return result;
+ }
+
+ /** See {@link Stream#collect(Collector)} */
+ public static <T, R, A> R collect(Iterator<T> iter, Collector<? super T, A, R> collector) {
+ A a = collect(iter, collector.supplier(), collector.accumulator());
+ return collector.finisher().apply(a);
}
/** Act on elements of an iterator.
@@ -230,29 +261,80 @@
/**
* Return true if every element of stream passes the filter (reads the
* stream until the first element not passing the filter)
+ * @deprecated Use {@link #allMatch}
*/
- public static <T> boolean every(Iterator<? extends T> stream, Predicate<T> filter) {
- while ( stream.hasNext() ) {
- T item = stream.next() ;
- if ( !filter.test(item) )
+ @Deprecated
+ public static <T> boolean every(Iterator<? extends T> iter, Predicate<T> predicate) {
+ return Iter.allMatch(iter, predicate);
+ }
+
+ /**
+ * Return true if every element of stream passes the filter (reads the
+ * stream until the first element not passing the filter)
+ */
+ public static <T> boolean allMatch(Iterator<T> iter, Predicate<? super T> predicate) {
+ while ( iter.hasNext() ) {
+ T item = iter.next() ;
+ if ( !predicate.test(item) )
return false ;
}
return true ;
}
+
+ /**
+ * Return true if one or more elements of stream passes the filter (reads
+ * the stream to first element passing the filter)
+ * @deprecated Use {@link #anyMatch}
+ */
+ @Deprecated
+ public static <T> boolean some(Iterator<T> iter, Predicate<? super T> predicate) {
+ return Iter.anyMatch(iter, predicate);
+ }
/**
* Return true if one or more elements of stream passes the filter (reads
* the stream to first element passing the filter)
*/
- public static <T> boolean some(Iterator<? extends T> stream, Predicate<T> filter) {
- while ( stream.hasNext() ) {
- T item = stream.next() ;
- if ( filter.test(item) )
+ public static <T> boolean anyMatch(Iterator<T> iter, Predicate<? super T> predicate) {
+ while ( iter.hasNext() ) {
+ T item = iter.next() ;
+ if ( predicate.test(item) )
return true ;
}
return false ;
}
+ /**
+ * Return true if none of the elements of the iterator passes the predicate test reads
+ * the stream to first element passing the filter)
+ */
+ public static <T> boolean noneMatch(Iterator<T> iter, Predicate<? super T> predicate) {
+ return ! anyMatch(iter, predicate);
+ }
+
+ /**
+ * Return an Optional with the first element of an iterator that matches the predicate.
+ * Return {@code Optional.empty} if none match.
+ * Reads the iterator until the first match.
+ */
+ public static <T> Optional<T> findFirst(Iterator<T> iter, Predicate<? super T> predicate) {
+ while ( iter.hasNext() ) {
+ T item = iter.next() ;
+ if ( predicate.test(item) )
+ return Optional.of(item);
+ }
+ return Optional.empty() ;
+ }
+
+ /**
+ * Return an Optional with an element of an iterator that matches the predicate.
+ * Return {@code Optional.empty} if none match.
+ * The element returned is not specified by the API contract.
+ */
+ public static <T> Optional<T> findAny(Iterator<T> iter, Predicate<? super T> predicate) {
+ return findFirst(iter, predicate);
+ }
+
// ---- Map
/** Apply a function to every element of an iterator, transforming it
@@ -525,35 +607,16 @@
count(iterator) ;
}
- // ---- String related helpers
- // Java8 has StringJoin
-
- public static <T> String asString(Iterable<T> stream) {
- return asString(stream, new AccString<T>()) ;
- }
-
- public static <T> String asString(Iterator<T> stream) {
- return asString(stream, new AccString<T>()) ;
- }
-
- public static <T> String asString(Iterable<T> stream, String sep) {
- return asString(stream, new AccString<T>(sep)) ;
- }
-
+ /** Create a string from an iterator, using the separator. Note: this consumes the iterator. */
public static <T> String asString(Iterator<T> stream, String sep) {
- return asString(stream, new AccString<T>(sep)) ;
+ return Iter.iter(stream).map(x->x.toString()).collect(Collectors.joining(sep));
}
-
- public static <T> String asString(Iterable<T> stream, AccString<T> formatter) {
- return asString(stream.iterator(), formatter) ;
+
+ /** Create a string from an iterator, using the separator, prefix and suffix. Note: this consumes the iterator. */
+ public static <T> String asString(Iterator<T> stream, CharSequence sep, CharSequence prefix, CharSequence suffix) {
+ return Iter.iter(stream).map(x->x.toString()).collect(Collectors.joining(sep, prefix, suffix));
}
-
- public static <T> String asString(Iterator<T> stream, AccString<T> formatter) {
- return reduce(stream, formatter) ;
- }
-
- // ----
-
+
public static <T> void close(Iterator<T> iter) {
if ( iter instanceof Closeable )
((Closeable)iter).close() ;
@@ -618,6 +681,7 @@
}
/** Send the elements of the iterable to a sink */
+ @Deprecated
public static <T> void sendToSink(Iterable<T> stream, Sink<T> sink) {
sendToSink(stream.iterator(), sink) ;
}
@@ -762,6 +826,11 @@
private Iter(Iterator<T> iterator) {
this.iterator = iterator ;
}
+
+ /** Apply the Consumer to each element of the iterator */
+ public void forEach(Consumer<T> action) {
+ iterator.forEachRemaining(action);
+ }
/** Consume the {@code Iter} and produce a {@code Set} */
public Set<T> toSet() {
@@ -776,7 +845,7 @@
public void sendToSink(Sink<T> sink) {
sendToSink(iterator, sink) ;
}
-
+
public T first() {
return first(iterator) ;
}
@@ -811,8 +880,8 @@
}
/** Return true if every element satisfies a predicate */
- public boolean every(Predicate<T> predciate) {
- return every(iterator, predciate) ;
+ public boolean every(Predicate<T> predicate) {
+ return every(iterator, predicate) ;
}
/** Return true if some element satisfies a predicate */
@@ -820,6 +889,26 @@
return some(iterator, filter) ;
}
+ public boolean allMatch(Predicate<? super T> predicate) {
+ return allMatch(iterator, predicate);
+ }
+
+ public boolean anyMatch(Predicate<? super T> predicate) {
+ return anyMatch(iterator, predicate);
+ }
+
+ public boolean noneMatch(Predicate<? super T> predicate) {
+ return noneMatch(iterator, predicate);
+ }
+
+ public Optional<T> findFirst(Predicate<? super T> predicate) {
+ return findFirst(iterator, predicate);
+ }
+
+ public Optional<T> findAny(Predicate<? super T> predicate) {
+ return findAny(iterator, predicate);
+ }
+
/** Remove nulls */
public Iter<T> removeNulls() {
return iter(removeNulls(this)) ;
@@ -842,13 +931,43 @@
return iter(operate(iterator, action)) ;
}
- /** Reduce by aggregator.
+ public <R> R foldLeft(R initial, Folder<T, R> accumulator) {
+ return foldLeft(iterator, initial, accumulator) ;
+ }
+
+ public <R> R foldRight(R initial, Folder<T, R> accumulator) {
+ return foldRight(iterator, initial, accumulator) ;
+ }
+
+ /** Reduce.
* This reduce is fold-left (take first element, apply to rest of list)
*/
- public <R> R reduce(Accumulate<T, R> aggregator) {
- return reduce(iterator, aggregator) ;
+ public Optional<T> reduce(BinaryOperator<T> accumulator) {
+ return reduce(iterator, accumulator) ;
}
+ public T reduce(T identity, BinaryOperator<T> accumulator) {
+ return Iter.reduce(iterator, identity, accumulator);
+ }
+
+ public Optional<T> min(Comparator<T> comparator) {
+ return min(iterator, comparator);
+ }
+
+ public Optional<T> max(Comparator<T> comparator) {
+ return max(iterator, comparator);
+ }
+
+ /** See {@link Stream#collect(Supplier, BiConsumer, BiConsumer)}, except without the {@code BiConsumer<R, R> combiner} */
+ public <R> R collect(Supplier<R> supplier, BiConsumer<R, T> accumulator/*, BiConsumer<R, R> combiner*/) {
+ return Iter.collect(iterator, supplier, accumulator);
+ }
+
+ /** See {@link Stream#collect(Collector)} */
+ public <R, A> R collect(Collector<? super T, A, R> collector) {
+ return collect(iterator, collector);
+ }
+
/** Apply an action to every element of an iterator */
public void apply(Consumer<T> action) {
apply(iterator, action) ;
@@ -925,15 +1044,8 @@
return action.getCount() ;
}
- public String asString() {
- return asString(iterator) ;
- }
-
- public String asString(String sep) {
- return asString(iterator, sep) ;
- }
-
- /** Return an {:@code Iter} that will see each element of the underlying iterator only once.
+ /**
+ * Return an {@code Iter} that will see each element of the underlying iterator only once.
* Note that this need working memory to remember the elements already seen.
*/
public Iter<T> distinct() {
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/StrUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/StrUtils.java
index 796a7ca..0b1989f 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/StrUtils.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/StrUtils.java
@@ -26,6 +26,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.stream.Collectors;
/** Some functions that act on strings */
public class StrUtils //extends StringUtils
@@ -42,28 +43,11 @@
return String.join("\n", args);
}
- /**
- * Concatentate strings, using a separator
- *
- * This function will be removed - do not use.
- *
- * @deprecated Prefer String.join(sep, args)
- */
- @Deprecated
- public static String strjoin(String sep, String... args) {
- return String.join(sep, args);
- }
-
/**
- * Concatentate strings, using a separator
- *
- * This function will be removed - do not use.
- *
- * @deprecated Prefer String.join(sep, args)
+ * Concatentate stringified objects, using a separator.
*/
- @Deprecated
- public static String strjoin(String sep, List<String> args) {
- return String.join(sep, args);
+ public static <X> String strjoin(List<X> args, String sep) {
+ return args.stream().map(obj->obj.toString()).collect(Collectors.joining(sep));
}
public static final int CMP_GREATER = +1 ;
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/iterator/TestIter.java b/jena-base/src/test/java/org/apache/jena/atlas/iterator/TestIter.java
index c803240..b00fcff 100644
--- a/jena-base/src/test/java/org/apache/jena/atlas/iterator/TestIter.java
+++ b/jena-base/src/test/java/org/apache/jena/atlas/iterator/TestIter.java
@@ -23,18 +23,20 @@
import static org.junit.Assert.assertTrue ;
import java.util.* ;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Test ;
public class TestIter
{
- List<String> data0 = new ArrayList<>() ;
- List<String> data1 = Arrays.asList("a") ;
- List<String> data2 = Arrays.asList("x","y","z") ;
- List<String> data3 = Arrays.asList(null, "x", null, null, null, "y", "z", null);
+ private List<String> data0 = new ArrayList<>() ;
+ private List<String> data1 = Arrays.asList("a") ;
+ private List<String> data2 = Arrays.asList("x","y","z") ;
+ private List<String> data3 = Arrays.asList(null, "x", null, null, null, "y", "z", null);
@Test
public void append_1() {
@@ -54,42 +56,37 @@
test(iter, "a", "x", "y", "z");
}
+ private static List<String> mutableList(String...strings) {
+ List<String> list = new ArrayList<>();
+ for ( String s : strings )
+ list.add(s);
+ return list;
+ }
+
@Test
public void append_4() {
- List<String> L = new ArrayList<>(3);
- L.add("a");
- L.add("b");
- L.add("c");
- List<String> R = new ArrayList<>(3);
- R.add("d");
- R.add("e");
- R.add("f");
+ List<String> L = mutableList("a", "b", "c");
+ List<String> R = mutableList("d", "e", "f");
Iterator<String> LR = Iter.append(L.iterator(), R.iterator());
while (LR.hasNext()) {
String s = LR.next();
-
if ( "c".equals(s) ) {
LR.hasNext(); // test for JENA-60
LR.remove();
}
}
- assertEquals("ab", Iter.asString(L, ""));
- assertEquals("def", Iter.asString(R, ""));
+ assertEquals(2, L.size());
+ assertEquals(Arrays.asList("a", "b"), L);
+ assertEquals(Arrays.asList("d", "e", "f"), R);
}
@Test
public void append_5() {
- List<String> L = new ArrayList<>(3);
- L.add("a");
- L.add("b");
- L.add("c");
- List<String> R = new ArrayList<>(3);
- R.add("d");
- R.add("e");
- R.add("f");
+ List<String> L = mutableList("a", "b", "c");
+ List<String> R = mutableList("d", "e", "f");
Iterator<String> LR = Iter.append(L.iterator(), R.iterator());
@@ -102,20 +99,14 @@
}
}
- assertEquals("abc", Iter.asString(L, ""));
- assertEquals("ef", Iter.asString(R, ""));
+ assertEquals(3, L.size());
+ assertEquals(Arrays.asList("e", "f"), R);
}
@Test
public void append_6() {
- List<String> L = new ArrayList<>(3);
- L.add("a");
- L.add("b");
- L.add("c");
- List<String> R = new ArrayList<>(3);
- R.add("d");
- R.add("e");
- R.add("f");
+ List<String> L = mutableList("a", "b", "c");
+ List<String> R = mutableList("d", "e", "f");
Iterator<String> LR = Iter.append(L.iterator(), R.iterator());
@@ -124,32 +115,9 @@
}
LR.remove();
- assertEquals("abc", Iter.asString(L, ""));
- assertEquals("de", Iter.asString(R, ""));
- }
-
- @Test
- public void asString_1() {
- String x = Iter.asString(data0, "");
- assertEquals("", x);
- }
-
- @Test
- public void asString_2() {
- String x = Iter.asString(data1, "");
- assertEquals("a", x);
- }
-
- @Test
- public void asString_3() {
- String x = Iter.asString(data1, "/");
- assertEquals("a", x);
- }
-
- @Test
- public void asString_4() {
- String x = Iter.asString(data2, "/");
- assertEquals("x/y/z", x);
+ assertEquals(3, L.size());
+ assertEquals(Arrays.asList("a", "b", "c"), L);
+ assertEquals(Arrays.asList("d", "e"), R);
}
private static void test(Iterator<? > iter, Object...items) {
@@ -165,28 +133,28 @@
@Test
public void fold_01() {
String[] x = {"a", "b", "c"};
- String z = Iter.foldLeft(Arrays.asList(x), f1, "X");
+ String z = Iter.foldLeft(Arrays.asList(x).iterator(), "X", f1);
assertEquals("Xabc", z);
}
@Test
public void fold_02() {
String[] x = {"a", "b", "c"};
- String z = Iter.foldRight(Arrays.asList(x), f1, "X");
+ String z = Iter.foldRight(Arrays.asList(x).iterator(), "X", f1);
assertEquals("Xcba", z);
}
@Test
public void fold_03() {
String[] x = {};
- String z = Iter.foldLeft(Arrays.asList(x), f1, "X");
+ String z = Iter.foldLeft(Arrays.asList(x).iterator(), "X", f1);
assertEquals("X", z);
}
@Test
public void fold_04() {
String[] x = {};
- String z = Iter.foldRight(Arrays.asList(x), f1, "X");
+ String z = Iter.foldRight(Arrays.asList(x).iterator(), "X", f1);
assertEquals("X", z);
}
@@ -355,6 +323,139 @@
int x = Iter.step(iter, 6);
assertEquals(5, x);
}
+
+ @SafeVarargs
+ private static <X> Iterator<X> data(X ... items) {
+ List<X> a = new ArrayList<>(items.length);
+ for (X x : items )
+ a.add(x);
+ return a.iterator();
+ }
+
+ @Test public void anyMatch1() {
+ boolean b = Iter.anyMatch(data("2"), x->x.equals("2"));
+ assertTrue(b);
+ }
+
+ @Test public void anyMatch2() {
+ boolean b = Iter.anyMatch(data("2","3"), x->x.equals("2"));
+ assertTrue(b);
+ }
+
+ @Test public void anyMatch3() {
+ boolean b = Iter.anyMatch(data("2","3"), x->x.equals("1"));
+ assertFalse(b);
+ }
+
+ @Test public void allMatch1() {
+ boolean b = Iter.allMatch(data("2", "2"), x->x.equals("2"));
+ assertTrue(b);
+ }
+
+ @Test public void allMatch2() {
+ boolean b = Iter.allMatch(data("1", "2"), x->x.equals("2"));
+ assertFalse(b);
+ }
+
+
+ @Test public void noneMatch1() {
+ boolean b = Iter.noneMatch(data("1", "2", "3"), x->x.equals("A"));
+ assertTrue(b);
+ }
+
+ @Test public void noneMatch2() {
+ boolean b = Iter.noneMatch(data("A", "2", "3"), x->x.equals("A"));
+ assertFalse(b);
+ }
+
+ @Test public void findFirst1() {
+ Optional<String> r = Iter.findFirst(data("A", "2", "3"), x->x.equals("A"));
+ assertTrue(r.isPresent());
+ assertEquals("A", r.get());
+ }
+
+ @Test public void findFirst2() {
+ Optional<String> r = Iter.findFirst(data("A", "2", "3"), x->x.equals("Z"));
+ assertFalse(r.isPresent());
+ }
+
+ @Test public void findAny1() {
+ Optional<String> r = Iter.findAny(data("A", "2", "3"), x->x.equals("A"));
+ assertTrue(r.isPresent());
+ assertEquals("A", r.get());
+ }
+
+ @Test public void reduce1() {
+ Optional<String> r = Iter.reduce(data("A", "2", "3"), String::concat);
+ assertEquals(Optional.of("A23"), r);
+ }
+
+ @Test public void reduce2() {
+ Optional<String> r = Iter.reduce(data("A"), String::concat);
+ assertEquals(Optional.of("A"), r);
+ }
+
+ @Test public void reduce3() {
+ Optional<String> r = Iter.reduce(data(), String::concat);
+ assertFalse(r.isPresent());
+ }
+
+ @Test public void min1() {
+ Optional<String> x = Iter.min(data(), String::compareTo);
+ assertFalse(x.isPresent());
+ }
+
+ @Test public void min2() {
+ Optional<String> x = Iter.min(data("2"), String::compareTo);
+ assertTrue(x.isPresent());
+ assertEquals("2", x.get());
+ }
+
+ @Test public void min3() {
+ Optional<String> x = Iter.min(data("1", "2", "3"), String::compareTo);
+ assertTrue(x.isPresent());
+ assertEquals("1", x.get());
+ }
+
+ @Test public void min4() {
+ Optional<String> x = Iter.min(data("3", "1", "2"), String::compareTo);
+ assertTrue(x.isPresent());
+ assertEquals("1", x.get());
+ }
+
+ @Test public void max1() {
+ Optional<String> x = Iter.max(data(), String::compareTo);
+ assertFalse(x.isPresent());
+ }
+
+ @Test public void max2() {
+ Optional<String> x = Iter.max(data("2"), String::compareTo);
+ assertTrue(x.isPresent());
+ assertEquals("2", x.get());
+ }
+
+ @Test public void max3() {
+ Optional<String> x = Iter.max(data("1", "2", "3"), String::compareTo);
+ assertTrue(x.isPresent());
+ assertEquals("3", x.get());
+ }
+
+ @Test public void max4() {
+ Optional<String> x = Iter.max(data("3", "1", "2"), String::compareTo);
+ assertTrue(x.isPresent());
+ assertEquals("3", x.get());
+ }
+
+ @Test public void collect3() {
+ List<String> x = Iter.collect(data("A", "B", "C"), Collectors.toList());
+ assertEquals(3, x.size());
+ assertEquals(Arrays.asList("A", "B", "C"), x);
+ }
+
+ @Test public void collect1() {
+ List<String> x = Iter.collect(data("A", "B", "C"), ArrayList::new, ArrayList::add);
+ assertEquals(Arrays.asList("A", "B", "C"), x);
+ }
@Test
public void take_01() {
@@ -366,6 +467,22 @@
}
@Test
+ public void forEach_1() {
+ List<String> data = Arrays.asList("1", "A", "B", "CC");
+ AtomicInteger counter = new AtomicInteger(0);
+ Iter.forEach(data.iterator(), x->counter.incrementAndGet());
+ assertEquals(4, counter.get());
+ }
+
+ @Test
+ public void forEach_2() {
+ List<String> data = Collections.emptyList();
+ AtomicInteger counter = new AtomicInteger(0);
+ Iter.forEach(data.iterator(), x->counter.incrementAndGet());
+ assertEquals(0, counter.get());
+ }
+
+ @Test
public void take_02() {
List<String> data = Arrays.asList("1", "A", "B", "CC");
List<String> data2 = Iter.take(data.iterator(), 0);
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/StageMatchTuple.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/StageMatchTuple.java
index 7a73c8f..d3c2460 100644
--- a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/StageMatchTuple.java
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/StageMatchTuple.java
@@ -25,6 +25,7 @@
import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.atlas.iterator.RepeatApplyIterator;
+import org.apache.jena.atlas.lib.StrUtils;
import org.apache.jena.atlas.lib.tuple.Tuple;
import org.apache.jena.atlas.lib.tuple.TupleFactory;
import org.apache.jena.graph.Node;
@@ -151,7 +152,7 @@
else
{
List<Tuple<NodeId>> r = Iter.toList(iter);
- String str = Iter.asString(r, "\n");
+ String str = StrUtils.strjoin(r, "\n");
System.err.println(str);
// Reset iter
iter = Iter.iter(r);
diff --git a/jena-sdb/src/main/java/org/apache/jena/sdb/compiler/SqlStageList.java b/jena-sdb/src/main/java/org/apache/jena/sdb/compiler/SqlStageList.java
index d033720..6ca5299 100644
--- a/jena-sdb/src/main/java/org/apache/jena/sdb/compiler/SqlStageList.java
+++ b/jena-sdb/src/main/java/org/apache/jena/sdb/compiler/SqlStageList.java
@@ -20,7 +20,7 @@
import java.util.ArrayList;
-import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.lib.StrUtils;
import org.apache.jena.sdb.core.SDBRequest ;
import org.apache.jena.sdb.core.sqlnode.SqlNode ;
@@ -49,7 +49,7 @@
if ( isEmpty() )
str = str + " (empty)" ;
else
- str = str + " "+ Iter.asString(this, " // " ) ;
+ str = str + " "+ StrUtils.strjoin(this, " // " ) ;
//str = str + "\n" ;
return str ;
}
diff --git a/jena-sdb/src/main/java/org/apache/jena/sdb/store/FeatureSet.java b/jena-sdb/src/main/java/org/apache/jena/sdb/store/FeatureSet.java
index 66316d8..a1e273a 100644
--- a/jena-sdb/src/main/java/org/apache/jena/sdb/store/FeatureSet.java
+++ b/jena-sdb/src/main/java/org/apache/jena/sdb/store/FeatureSet.java
@@ -21,10 +21,10 @@
import java.util.ArrayList ;
import java.util.Iterator ;
import java.util.List ;
+import java.util.stream.Collectors;
import org.apache.jena.atlas.io.IndentedWriter ;
import org.apache.jena.atlas.io.PrintableBase ;
-import org.apache.jena.atlas.iterator.Iter ;
/** A set of features (order retained */
@@ -61,6 +61,7 @@
@Override
public void output(IndentedWriter out)
{
- out.print(Iter.asString(features)) ;
+ String x = features.stream().map(f->f.toString()).collect(Collectors.joining(" ")) ;
+ out.print(x) ;
}
}
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/lib/Lib2.java b/jena-tdb/src/main/java/org/apache/jena/tdb/lib/Lib2.java
deleted file mode 100644
index c92ef09..0000000
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/lib/Lib2.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jena.tdb.lib;
-
-
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.apache.jena.atlas.iterator.Iter ;
-
-
-public class Lib2
-{
- private static Pattern p = Pattern.compile("http:[^ \n]*[#/]([^/ \n]*)") ;
- /** Abbreviate, crudely, URI in strings, leaving only their last component. */
- public static String printAbbrev(Object obj)
- {
- if ( obj==null )
- return "<null>" ;
- String x = obj.toString() ;
- return p.matcher(x).replaceAll("::$1") ;
- }
-
- /** Abbreviate, crudely, URI in strings, leaving only their last component. */
- public static <T> String printAbbrevList(List<T> objs)
- {
- String x = Iter.asString(objs, "\n") ;
- return printAbbrev(x) ;
- }
-}
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/solver/SolverLib.java b/jena-tdb/src/main/java/org/apache/jena/tdb/solver/SolverLib.java
index ff54d73..120eb5e 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/solver/SolverLib.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/solver/SolverLib.java
@@ -19,7 +19,6 @@
package org.apache.jena.tdb.solver;
import static org.apache.jena.atlas.lib.tuple.TupleFactory.tuple ;
-import static org.apache.jena.tdb.lib.Lib2.printAbbrev ;
import java.util.* ;
import java.util.function.Function;
@@ -314,14 +313,6 @@
return new QueryIterTDB(iterBinding, killList, input, execCxt) ;
}
- /** Turn a BasicPattern into an abbreviated string for debugging */
- public static String strPattern(BasicPattern pattern)
- {
- List<Triple> triples = pattern.getList() ;
- String x = Iter.asString(triples, "\n ") ;
- return printAbbrev(x) ;
- }
-
public static Set<NodeId> convertToNodeIds(Collection<Node> nodes, DatasetGraphTDB dataset)
{
Set<NodeId> graphIds = new HashSet<>() ;
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/solver/StageMatchTuple.java b/jena-tdb/src/main/java/org/apache/jena/tdb/solver/StageMatchTuple.java
index b19fd32..8054343 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/solver/StageMatchTuple.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/solver/StageMatchTuple.java
@@ -19,10 +19,9 @@
package org.apache.jena.tdb.solver;
-import static org.apache.jena.atlas.lib.tuple.TupleFactory.* ;
+import static org.apache.jena.atlas.lib.tuple.TupleFactory.asTuple;
import java.util.Iterator;
-import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -146,21 +145,6 @@
return Iter.iter(iterMatches).map(binder).removeNulls() ;
}
- private static Iterator<Tuple<NodeId>> print(Iterator<Tuple<NodeId>> iter)
- {
- if ( ! iter.hasNext() )
- System.err.println("<empty>") ;
- else
- {
- List<Tuple<NodeId>> r = Iter.toList(iter) ;
- String str = Iter.asString(r, "\n") ;
- System.err.println(str) ;
- // Reset iter
- iter = Iter.iter(r) ;
- }
- return iter ;
- }
-
private static boolean reject(BindingNodeId output , Var var, NodeId value)
{
if ( ! output.containsKey(var) )