从现有列表中提取结果集的公共代码可以如下:
List<Node> results;
for (Node node : rsp.getNodes()) {
if (node.isValid() && node.getType == NodeType.TEST &&...) {
if (results == null) {
results = new ArrayList<>();
}
results.add(node);
}
}
Run Code Online (Sandbox Code Playgroud)
现在使用java 8和lambdas,因为建议总是使用流来支持?
rsp.getNodes().stream.filter(node -> {
return node.isValid() && node.getType == NodeType.TEST &&...;
}).forEach(node -> results.add(node));
Run Code Online (Sandbox Code Playgroud)
对我来说,最近从java8开始,这看起来并不比现在的java7代码更清晰.无论如何你有更多的经验,并且可以肯定地推荐我使用这些类型的"快捷方式"与lambdas,而不是旧的foreach风格?
我知道最后它可能是一个品味问题.如果是的话,你会觉得我的例子是一个完全可行的情况下,可以始终与流和lambda表达式作为一个很好的做法(我有意识地不使用术语"最佳实践")所取代?
使用Java 8中的流API,createObjects()下面将返回X单行中的对象列表.
public class StreamObjectCreator {
public List<X> createObjects(Integer... s) {
return Arrays.stream(s).map(X::new).collect(Collectors.toList());
}
private static class X {
int s;
public X(int s) {
this.s = s;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,考虑以下枚举Y:
private static enum Y {
VALUE_1(2), VALUE_2(1);
private int i;
private Y(int i) {
this.i = i;
}
public int getI() {
return i;
}
}
Run Code Online (Sandbox Code Playgroud)
我想做类似的事情并返回以下列表:
[VALUE_1,VALUE_1,VALUE_2]
换句话说,i每个枚举值的出现.
使用"旧的"Java方式,它可以像这样实现.
List<Y> createEnumList() {
List<Y> list = new ArrayList<Y>();
for (Y …Run Code Online (Sandbox Code Playgroud) 现在我有一个HashMap,我试图减少到总数.这是当前的代码:
HashMap map = new HashMap<String, Long>();
map.put("ex1", 757L);
map.put("ex2", 77L);
map.values()
.stream()
.reduce(0L, (a, b) -> a + b);
Run Code Online (Sandbox Code Playgroud)
有没有更优雅的方式来做到这一点?我想使用sum方法.
根据主题:如何在流中获得大于10的第一个数字?
stream()在这种情况下,有什么方法可以帮助吗?
我希望一旦流到达10以上的第一个元素,它将返回它而不循环其余元素.(有点"打破"循环)有可能吗?
/sf/answers/1657259201/为生成连续整数列表提供了一个很好的解决方案.看到JDK8没有提供ShortStream类,你会如何生成一个连续短裤列表?
我正在寻找以下内容:
List<Short> range = ShortStream.range(0, 500).boxed().collect(Collectors.toList());
其中输出包含一个从0到500(包括0和500)的短路列表.
在Java 8 In Action,7.1.1节中,作者声明通过添加函数,流可以从并行处理中受益.parallel().它们提供了一种简单的方法parallelSum(int)来说明这一点.我很好奇它看起来有多好,所以我执行了这段代码:
package lambdasinaction.chap7;
import java.util.stream.Stream;
public class ParallelPlay {
public static void main(String[] args) {
System.out.println(parallelSum(100_000_000));
}
public static long parallelSum(long n) {
return Stream.iterate(1L, i -> i + 1)
.limit(n)
.parallel()
.reduce(0L, Long::sum);
}
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,我收到了这个错误:
Exception in thread "main" java.lang.OutOfMemoryError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.util.concurrent.ForkJoinTask.getThrowableException(Unknown Source)
at java.util.concurrent.ForkJoinTask.reportException(Unknown Source)
at java.util.concurrent.ForkJoinTask.invoke(Unknown Source)
at java.util.stream.SliceOps$1.opEvaluateParallelLazy(Unknown Source)
at java.util.stream.AbstractPipeline.sourceSpliterator(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown …Run Code Online (Sandbox Code Playgroud) 我有一张看起来像这样的地图:
Map<String,String[]> urlFormEncoded = new HashMap<String,String[]>();
Run Code Online (Sandbox Code Playgroud)
我想将存储在String []数组中的所有值作为double值求和,我试过这样的事情:
double requestAmount = urlFormEncoded.entrySet().stream().mapToDouble(k -> Arrays.stream(k.getValue()).).sum();
Run Code Online (Sandbox Code Playgroud)
但不幸的是我不知道如何将此String []转换为值:(我想使用流和lambda表达式来做到这一点
在中Java8,让List<Item> list我按以下顺序进行处理:
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
for (int i1 = 0; i1 < list.size() - 1; i1++) {
Item item1 = list.get(i1);
for (int i2 = i1 + 1; i2 < list.size(); i2++) {
Item item2 = list.get(i2);
doSomething(item1, item2);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,我处理列表中所有有序的项目对(索引item1<的索引,<的索引item2)。现在,我想doSomething(item1, item2)为每个有序对并行运行函数。实现这一目标的最佳策略是什么?对最快的代码感兴趣。Java8流欢迎。
doSomething比如做:map.put(item1.key + " " + item2.key, item1.val + item2.val);。
有序对的数量n * (n - 1) / 2,其中 …
实际任务是能够通过从文件中读取来返回Stream,但是这样做而不将整个文件(或解析的集合)完全加载到内存中.该流的目的可以在以后确定 - 例如保存到DB.开发人员将拥有反序列化流的句柄(而不是反序列化的集合).
问题是,不能保证文件中的一行等于一个MyEntity对象(在这种情况下我可以使用这篇文章:http://blog.codeleak.pl/2014/05/parsing-file-with -stream-api-in-java-8.html)
通常,可以找到这样的情况:如果输入流,则需要返回通过将可变数量的输入流项映射到一个输出流项而构造的输出流.
所以,到目前为止,我的解决方案是使用供应商,如下所示:
public class Parser{
public Stream<MyEntity> parse(final InputStream stream) {
return Stream.generate(new AggregatingSupplier(stream));
}
private class AggregatingSupplier implements Supplier<MyEntity> {
private final Scanner r;
public AggregatingSupplier(final InputStream source) {
this.r= new Scanner(source);
}
@Override
public MyEntity get() {
MyEntity re=new MyEntity();
while (r.hasNextLine() &&!re.isComplete()){
String line=r.nextLine();
// ... do some processing
}
return re;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法的问题在于使用Stream.generate获得的流是无限的.没有停止条件.抛出一个异常(有点).或者选择完全不同的(经典)方法.
我有一个Java 8流的问题,其中数据是以突然的批量处理,而不是在请求时.我有一个相当复杂的流 - 流,必须并行化,因为我concat用来合并两个流.
我的问题源于这样一个事实,即数据似乎在大量分钟内 - 有时甚至是数小时 - 被解析.我希望一旦Stream读取传入数据就会发生这种处理,以分散工作量.批量处理几乎在所有方面都是违反直觉的.
所以,问题是为什么这个批量收集发生以及如何避免它.
我的输入是一个未知大小的Spliterator,我使用forEach作为终端操作.