我正在寻找一种简洁的方法来将Iterator一个Stream或更具体的转换为"视图"迭代器作为流.
出于性能原因,我想在新列表中避免使用迭代器的副本:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Collection<String> copyList = new ArrayList<String>();
sourceIterator.forEachRemaining(copyList::add);
Stream<String> targetStream = copyList.stream();
Run Code Online (Sandbox Code Playgroud)
根据评论中的一些建议,我也尝试使用Stream.generate:
public static void main(String[] args) throws Exception {
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream<String> targetStream = Stream.generate(sourceIterator::next);
targetStream.forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
但是,我得到了NoSuchElementException(因为没有调用hasNext)
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(AbstractList.java:364)
at Main$$Lambda$1/1175962212.get(Unknown Source)
at java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef.tryAdvance(StreamSpliterators.java:1351)
at java.util.Spliterator.forEachRemaining(Spliterator.java:326)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at Main.main(Main.java:20)
Run Code Online (Sandbox Code Playgroud)
我已经看过StreamSupport和Collections,但我没有发现任何东西.
我有一个返回的界面java.lang.Iterable<T>.
我想使用Java 8 Stream API来操纵该结果.
但是Iterable不能"流".
知道如何将Iterable用作Stream而不将其转换为List吗?
我有两个数字列表,我想找到所有可能的数字对.例如,给定列表[1,2,3]和[3,4],结果应该是[(1,3),(1,4),(2,3),(2,4),(3) ,3),(3,4)].
我知道我可以使用for循环来做到这一点,但有没有更简洁的方法来使用Java 8流?
我试过以下但是我错过了一些东西,因为我得到了List<Stream<int[]>>而不是List<int[]>.
public static void main(String[] args) {
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(3, 4);
List<int[]> pairs = list1.stream().map(i -> list2.stream().map(j -> new int[] { i, j }))
.collect(Collectors.toList());
pairs.forEach(i -> {
System.out.println("{" + i[0]+ "," + i[1]+ "}");
});
}
Run Code Online (Sandbox Code Playgroud) 我想创建一个方法来创建一个元素流,这些元素是多个给定流的笛卡尔积(由二元运算符在末尾聚合到相同类型).请注意,参数和结果都是流,而不是集合.
例如,对于{A,B}和{X,Y}的两个流,我希望它生成值{AX,AY,BX,BY}的流(简单串联用于聚合字符串).到目前为止,我已经提出了这个代码:
private static <T> Stream<T> cartesian(BinaryOperator<T> aggregator, Stream<T>... streams) {
Stream<T> result = null;
for (Stream<T> stream : streams) {
if (result == null) {
result = stream;
} else {
result = result.flatMap(m -> stream.map(n -> aggregator.apply(m, n)));
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
这是我想要的用例:
Stream<String> result = cartesian(
(a, b) -> a + b,
Stream.of("A", "B"),
Stream.of("X", "Y")
);
System.out.println(result.collect(Collectors.toList()));
Run Code Online (Sandbox Code Playgroud)
预期结果:AX, AY, BX, BY.
另一个例子:
Stream<String> result = …Run Code Online (Sandbox Code Playgroud) 我遇到了这篇文章,它非常努力地解释了打印所有字符串的递归解决方案。
public class Main {
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0)
System.out.println(prefix);
else {
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i),
str.substring(0, i) + str.substring(i + 1));
}
}
public static void main(String[] args) {
permutation("", "ABCD");
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我们开始从堆栈中弹出时,我仍然无法获得该部分。例如,递归一直进行到permutation("ABCD",""),在基本情况下遇到并打印ABCD。但是现在会发生什么?我们permutation("ABC","D")从函数调用堆栈中弹出。我们如何处理这个等等?
有人可以帮忙解释一下吗?
另外,我需要一些有关此时间复杂度的指针。不像完整的计算,而是一些提示。
现在我只能实现两个集合的笛卡尔积,这里是代码:
public static <T1, T2, R extends Collection<Pair<T1, T2>>>
R getCartesianProduct(
Collection<T1> c1, Collection<T2> c2,
Collector<Pair<T1, T2>, ?, R> collector) {
return c1.stream()
.flatMap(e1 -> c2.stream().map(e2 -> new Pair<>(e1, e2)))
.collect(collector);
}
Run Code Online (Sandbox Code Playgroud)
这段代码在IntelliJ中工作正常,但在Eclipse中没有(编译器合规级别为1.8):
The method collect(Collector<? super Object,A,R>)
in the type Stream<Object> is not applicable for
the arguments (Collector<Pair<T1,T2>,capture#5-of ?,R>)
Run Code Online (Sandbox Code Playgroud)
这是Pair.java:
public class Pair<T1, T2> implements Serializable {
protected T1 first;
protected T2 second;
private static final long serialVersionUID = 1360822168806852921L;
public Pair(T1 first, T2 second) …Run Code Online (Sandbox Code Playgroud) 我是Streams的新手Java 8,目前正在尝试解决这个问题,我有两个列表如下:
List<Integer> list1 = Arrays.asList(5, 11,17,123);
List<Integer> list2 = Arrays.asList(124,14,80);
Run Code Online (Sandbox Code Playgroud)
我想找到这些列表中所有元素之间存在的绝对最小差异.
预期结果: 1(124-123=1)
使用Java 7实现它不是问题,但我如何使用Java8的Streams实现它?我如何迭代forEach元素List1,也forEach来自List2和保持最小值?
我可以在 Scala 中使用以下方法轻松实现这一点:
def permute(xs: List[Int], ys: List[Int]) = {
for {x <- xs; y <- ys} yield (x,y)
}
Run Code Online (Sandbox Code Playgroud)
所以如果我给它 {1, 2}, {3, 4} 我返回 {1, 3}, {1, 4}, {2, 3}, {2, 4}
我希望能够使用流将其转换为 java 8。
我遇到了一些困难,我希望能够将其扩展得更远,因为我希望能够从两个以上的列表中生成许多排列的测试样本。
即使使用流,它是否也不可避免地会成为嵌套的混乱,还是我不够应用自己?
在意识到我正在寻找笛卡尔积后发现了一些额外的答案:
java ×7
java-8 ×6
java-stream ×5
anagram ×1
collections ×1
generics ×1
iterable ×1
iterator ×1
lambda ×1
permutation ×1
recursion ×1
scala ×1
set ×1
string ×1