这是一个例子:代码A:
files.forEach(f -> {
//TODO
});
Run Code Online (Sandbox Code Playgroud)
和另一个代码B可以这样使用:
files.stream().forEach(f -> { });
Run Code Online (Sandbox Code Playgroud)
两者之间有什么区别,有stream()没有stream()?
通过在Java中编写应用程序,有许多用例java.util.Collection.自从java.util.stream.StreamJava 8引入以来,我遇到了一些难以决定使用的用例.
例如:您将编写一些util-methods.
public static List<?> filterHashToList(int hash, Collection<?> toFilter) {
return toFilter.stream()
.filter((Object o) -> hash == o.hashCode())
.collect(Collectors.toCollection(LinkedList::new));
}
Run Code Online (Sandbox Code Playgroud)
怎么样这样写:
public static List<?> filterHashToList(int hash, Collection<?> toFilter) {
List<Object> result = new LinkedList<>();
for(Object o : toFilter) {
if(hash == o.hashCode()) {
result.add(o);
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
两种方法都会产生相同的结果.java.util.stream.Stream并且java.util.stream.Collector是接口,因此如果我使用自定义流和收集器,实现也会有所不同.
我认为有很多实现使用旧的fashoined循环方式.
那么,是否有可能通过用例回答使用,流或循环的内容?如果是这样,是否必须在适当的时候更新所有实施?
或者我应该通过实现util-methods提供两种方式?或者我是否应该在过滤过程之后提供一个返回流的mthed,以便在需要时也可以使用该流?
我有以下代码:
Stream.of("1,2,3,4".split(",")).mapToDouble(Double::valueOf).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我想回来List<Double>.
此代码无法编译.
我看到错误:
Error:(57, 69) java: method collect in interface java.util.stream.DoubleStream cannot be applied to given types;
required: java.util.function.Supplier<R>,java.util.function.ObjDoubleConsumer<R>,java.util.function.BiConsumer<R,R>
found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.List<java.lang.Object>>
reason: cannot infer type-variable(s) R
(actual and formal argument lists differ in length)
Run Code Online (Sandbox Code Playgroud)
如何解决这个问题?
或者,有没有更好的方法来做到这一点,我错过了?我想基于供应商创建一个流(通常是无限的),但是当供应商返回null时,流终止.我自己做了这个,但是完成一个非常简单的概念似乎是相当多的工作.
public class NullTerminatedStreamFactory {
static int characteristics = Spliterator.ORDERED | Spliterator.DISTINCT;
public static<T> Stream<T> makeNullTerminatedStream(Supplier<T> supplier) {
return StreamSupport.stream(new NullTerminatedSpliteratorFromSupplier<>(supplier, Long.MAX_VALUE, characteristics), false);
}
static class NullTerminatedSpliteratorFromSupplier<T> extends Spliterators.AbstractSpliterator<T> {
public NullTerminatedSpliteratorFromSupplier(Supplier<T> supplier, long est, int additionalCharacteristics) {
super(est, additionalCharacteristics);
this.supplier = supplier;
}
public Supplier<T> supplier;
@Override
public boolean tryAdvance(Consumer<? super T> action) {
T next = supplier.get();
if (next != null) {
action.accept(next);
return true;
}
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了记录,我正在使用它,基本上从BlockingQueue创建一个Stream:
NullTerminatedStreamFactory.makeNullTerminatedStream(() -> {
try { …Run Code Online (Sandbox Code Playgroud) 我想将两个Map与JAVA 8 Stream合并:
Map<String, List<String>> mapGlobal = new HashMap<String, List<String>>();
Map<String, List<String>> mapAdded = new HashMap<String, List<String>>();
Run Code Online (Sandbox Code Playgroud)
我尝试使用此实现:
mapGlobal = Stream.of(mapGlobal, mapAdded)
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.toList())
));
Run Code Online (Sandbox Code Playgroud)
但是,此实现仅创建如下结果:
Map<String, List<Object>>
如果未包含一个密钥mapGlobal,则将其添加为具有相应List字符串的新密钥.如果钥匙被复制中mapGlobal和mapAdded,值的列表都将被合并为:A = {1, 3, 5, 7}和B = {1, 2, 4, 6}然后A ? B = {1, 2, 3, 4, 5, 6, 7}.
我需要在lambda中抛出异常,我不知道该怎么做.
到目前为止,这是我的代码:
listOfProducts
.stream()
.filter(product -> product.getProductId().equalsIgnoreCase(productId))
.filter(product -> product == null) //like if(product==null) throw exception
.findFirst()
.get()
Run Code Online (Sandbox Code Playgroud)
我不知道该怎么做.有没有办法做到这一点,或者我只是通过应用过滤器绕过它,以便过滤器不会转发空值
filter(product->product!=null)(即使一个提示将是有用的:))
编辑实际问题是我需要一个产品,如果它是null然后它将抛出异常,否则它将通过,在Java 8 Lambda函数中没有提到抛出异常?
我试图重构的代码是
for(Product product : listOfProducts) {
if(product!=null && product.getProductId()!=null &&
product.getProductId().equals(productId)){
productById = product;
break;
}
}
if(productById == null){
throw new IllegalArgumentException("No products found with the
product id: "+ productId);
}
Run Code Online (Sandbox Code Playgroud)
我有另一个可能的解决方案
public Product getProductById(String productId) {
Product productById = listOfProducts.stream()
.filter(product -> product.getProductId().equalsIgnoreCase(productId)).findFirst().get();
if (productById == null)
throw new IllegalArgumentException("product …Run Code Online (Sandbox Code Playgroud) 将流的元素收集到集合中时,是否还有.distinct()在流上指定的优点(或缺点)?例如:
return items.stream().map(...).distinct().collect(toSet());
Run Code Online (Sandbox Code Playgroud)
鉴于该集合已经删除了重复项,这似乎是多余的,但它是否提供任何性能优势或劣势?答案取决于流是并行/顺序还是有序/无序?
例如,我有一个名字和姓氏的人.
我想从人员列表中收集一个字符串列表(姓名和姓氏),但似乎我不能每个列表使用两次地图或者每个列表不能使用两次流.我的代码是:
persons.stream()
.map(Person::getName)
.collect(Collectors.toSet())
.stream().map(Person::getSurname)
.collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)
但它一直告诉我,Person静态方法不能引用非静态方法.
我究竟做错了什么?
我正在进行服务电话并尝试处理响应.响应可能有一个列表.该列表可能为null.
此外,如果列表不为null或不为空,则需要对其进行过滤.在代码"entry"中,如果过滤不提供任何内容或响应列表为空或null,则引用可能为null.
目前,当我尝试在空响应列表上使用stream()时,我正在获取NPE.我该如何处理这种情况?
@Getter
public class ServiceResponse {
List<ResponseEntry> entryList;
}
@Getter
public class ResponseEntry {
String value;
}
ServiceResponse serviceResponse = service.getServiceResponse();
ResponseEntry entry = serviceResponse.getEntryList()
.stream()
.filter(e -> "expectedValue".equals(e.getValue()))
.findFirst()
.orElse(null);
if (entry == null) { ... }
Run Code Online (Sandbox Code Playgroud)
JDK 正在引入一个Stream.toList()带有JDK-8180352的 API 。这是一个基准代码,我试图将其性能与现有的进行比较Collectors.toList:
@BenchmarkMode(Mode.All)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 20, time = 1, batchSize = 10000)
@Measurement(iterations = 20, time = 1, batchSize = 10000)
public class CollectorsVsStreamToList {
@Benchmark
public List<Integer> viaCollectors() {
return IntStream.range(1, 1000).boxed().collect(Collectors.toList());
}
@Benchmark
public List<Integer> viaStream() {
return IntStream.range(1, 1000).boxed().toList();
}
}
Run Code Online (Sandbox Code Playgroud)
结果总结如下:
Benchmark Mode Cnt Score Error Units
CollectorsVsStreamToList.viaCollectors thrpt 20 17.321 ± 0.583 ops/s
CollectorsVsStreamToList.viaStream thrpt 20 23.879 ± 1.682 ops/s
CollectorsVsStreamToList.viaCollectors avgt 20 0.057 ± …Run Code Online (Sandbox Code Playgroud) java ×10
java-stream ×10
java-8 ×8
lambda ×3
collections ×2
collect ×1
collectors ×1
exception ×1
java-16 ×1
jmh ×1
loops ×1
optional ×1
performance ×1