看看下面的课程我做了:
public class FibonacciSupplier implements Iterator<Integer> {
private final IntPredicate hasNextPredicate;
private int beforePrevious = 0;
private int previous = 1;
private FibonacciSupplier(final IntPredicate hasNextPredicate) {
this.hasNextPredicate = hasNextPredicate;
}
@Override
public boolean hasNext() {
return hasNextPredicate.test(previous);
}
@Override
public Integer next() {
int result = beforePrevious + previous;
beforePrevious = previous;
previous = result;
return result;
}
public static FibonacciSupplier infinite() {
return new FibonacciSupplier(i -> true);
}
public static FibonacciSupplier finite(final IntPredicate predicate) {
return new FibonacciSupplier(predicate);
} …Run Code Online (Sandbox Code Playgroud) 当我执行此代码时,它会在流管道中打开大量文件:
public static void main(String[] args) throws IOException {
Files.find(Paths.get("JAVA_DOCS_DIR/docs/api/"),
100, (path, attr) -> path.toString().endsWith(".html"))
.map(file -> runtimizeException(() -> Files.lines(file, StandardCharsets.ISO_8859_1)))
.map(Stream::count)
.forEachOrdered(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
我得到一个例外:
java.nio.file.FileSystemException: /long/file/name: Too many open files
Run Code Online (Sandbox Code Playgroud)
问题是Stream.count当流完成后不会关闭流.但鉴于它是终端操作,我不明白为什么不应该这样做.对于诸如reduce和之类的其他终端操作也是如此forEach.flatMap另一方面关闭它所包含的流.
该文档告诉我使用try-with-resouces语句在必要时关闭流.在我的情况下,我可以count用这样的东西替换线:
.map(s -> { long c = s.count(); s.close(); return c; } )
Run Code Online (Sandbox Code Playgroud)
但这很嘈杂,并且在某些情况下可能会给大型复杂的管道带来真正的不便.
所以我的问题如下:
runtimizeException是一种在RuntimeExceptions 中包装已检查异常的方法.
我是一个ETL进程,我从Spring Data Repository中检索了很多实体.然后我使用并行流将实体映射到不同的实体.我可以使用使用者将这些新实体逐个存储在另一个存储库中,或者将它们收集到List中并将其存储在单个批量操作中.第一种是昂贵的,而后者可能超过可用的内存.
有没有一种很好的方法来收集流中的一定数量的元素(如限制),消耗该块,并继续并行处理直到所有元素都被处理?
我使用Java 8进行数据分组.但获得的结果不是按顺序形成的.
Map<GroupingKey, List<Object>> groupedResult = null;
if (!CollectionUtils.isEmpty(groupByColumns)) {
Map<String, Object> mapArr[] = new LinkedHashMap[mapList.size()];
if (!CollectionUtils.isEmpty(mapList)) {
int count = 0;
for (LinkedHashMap<String, Object> map : mapList) {
mapArr[count++] = map;
}
}
Stream<Map<String, Object>> people = Stream.of(mapArr);
groupedResult = people
.collect(Collectors.groupingBy(p -> new GroupingKey(p, groupByColumns), Collectors.mapping((Map<String, Object> p) -> p, toList())));
public static class GroupingKey
public GroupingKey(Map<String, Object> map, List<String> cols) {
keys = new ArrayList<>();
for (String col : cols) {
keys.add(map.get(col));
}
}
// Add …Run Code Online (Sandbox Code Playgroud) 假设我们尝试向java 8流应用一个可能抛出已检查异常的lambda:
Stream<String> stream = Stream.of("1", "2", "3");
Writer writer = new FileWriter("example.txt");
stream.forEach(s -> writer.append(s)); // Unhandled exception: java.io.IOException
Run Code Online (Sandbox Code Playgroud)
这不会编译.
一种解决方法是嵌套已检查的异常,RuntimeException但它使以后的异常处理变得复杂,而且它只是丑陋:
stream.forEach(s -> {
try {
writer.append(s);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
Run Code Online (Sandbox Code Playgroud)
另一种解决方法可能是转换有限的功能forEach,以普通的旧的foreach 循环是比较友好的检查的异常.
但天真的方法失败了:
for (String s : stream) { // for-each not applicable to expression type 'java.util.stream.Stream<java.lang.String>'
writer.append(s);
}
for (String s : stream.iterator()) { // foreach not applicable to type 'java.util.Iterator<java.lang.String>'
writer.append(s);
} …Run Code Online (Sandbox Code Playgroud) 我想采取以下方法:
public BigDecimal mean(List<BigDecimal> bigDecimals, RoundingMode roundingMode) {
BigDecimal sum = BigDecimal.ZERO;
int count=0;
for(BigDecimal bigDecimal : bigDecimals) {
if(null != bigDecimal) {
sum = sum.add(bigDecimal);
count++;
}
}
return sum.divide(new BigDecimal(count), roundingMode);
}
Run Code Online (Sandbox Code Playgroud)
并使用Streams api更新它.这是我到目前为止所得到的:
public BigDecimal average(List<BigDecimal> bigDecimals, RoundingMode roundingMode) {
BigDecimal sum = bigDecimals.stream()
.map(Objects::requireNonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
long count = bigDecimals.stream().filter(Objects::nonNull).count();
return sum.divide(new BigDecimal(count), roundingMode);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在没有两次流式传输的情况下做到这一点(第二次获得计数)?
在Java的API 8说:
在执行管道的终端操作之前,不会开始遍历管道源.
那么为什么以下代码抛出:
java.lang.IllegalStateException:stream已经被操作或关闭
Stream<Integer> stream = Stream.of(1,2,3);
stream.filter( x-> x>1 );
stream.filter( x-> x>2 ).forEach(System.out::print);
Run Code Online (Sandbox Code Playgroud)
根据API的第一个过滤操作不应该在Stream上操作.
我正在学习Java 8中的Streams.我对这个概念感到困惑:
集合是内存中的数据结构,它保存数据结构当前具有的所有值 - 集合中的每个元素必须先计算才能添加到集合中.相反,流是概念上固定的数据结构,其中元素是按需计算的.
我不明白.Collection如何才能保存在添加到集合之前必须已计算的值?而且,Stream与固定数据结构的比较是什么意思?
我正在尝试使用Java 8的新功能(例如s)从Hacker Rank站点的Bit Manipulation部分解决以下问题.Stream
问题描述:
给定一个整数n,找到每个x,使得:
- 0 <= x <= n
- n + x = n ^ x
其中^表示按位XOR运算符.然后打印一个整数,表示满足上述条件的x的总数.
约束
- 0 <= n <= 10 15
样本输入: 5
样本输出: 2
说明:
对于n = 5,x值0和2满足条件:
- 5 + 0 = 5 ^ 0 = 5
- 5 + 2 = 5 ^ 2 = 7
因此,我们打印2作为我们的答案.
样本输入: 10
样本输出: 4
说明: 对于N = 10,该X值0 …
在P下面的类中,该方法test似乎返回相同false:
import java.util.function.IntPredicate;
import java.util.stream.IntStream;
public class P implements IntPredicate {
private final static int SIZE = 33;
@Override
public boolean test(int seed) {
int[] state = new int[SIZE];
state[0] = seed;
for (int i = 1; i < SIZE; i++) {
state[i] = state[i - 1];
}
return seed != state[SIZE - 1];
}
public static void main(String[] args) {
long count = IntStream.range(0, 0x0010_0000).filter(new P()).count();
System.out.println(count);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,将 classP与结合使用 …
java-stream ×10
java ×8
java-8 ×8
collections ×2
algorithm ×1
arrays ×1
bigdecimal ×1
collect ×1
for-loop ×1
foreach ×1
grouping ×1
iterator ×1
java-11 ×1
simd ×1
xor ×1