我有一系列未分类的项目和一组比较器.我想通过使用"thenComparing"(Multisort)将所有比较器应用到流中.是否有比以下代码更优雅的方式来实现这一点?
Stream unsorted = ...;
Stream<Comparator> comparators = ...;
Comparator compareFunc = comparators.reduce(null, (a, b) -> {
if(a == null) {
return b;
}else {
return a.thenComparing(b);
}
});
Stream result = unsorted.sorted(compareFunc);
Run Code Online (Sandbox Code Playgroud) 我有一个Java中的哈希映射,我需要限制其大小(50000的顺序).但我应该只删除最旧的项目.项的时间戳存储在条目对象的字段中:
Map<String, MyModel> snapshot = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
和
public class MyModel {
private ZonedDateTime createdAt;
// other fields...
}
Run Code Online (Sandbox Code Playgroud)
我还按时间戳顺序将它们插入到地图中.
完成这种删除最旧条目的最有效方法是什么?请注意,时间"阈值"未知,只有Map的最终大小.
我有一个类定义的类
public class TimePeriodCalc {
private double occupancy;
private double efficiency;
private String atDate;
}
Run Code Online (Sandbox Code Playgroud)
我想使用Java 8 Stream API执行以下SQL语句.
SELECT atDate, AVG(occupancy), AVG(efficiency)
FROM TimePeriodCalc
GROUP BY atDate
Run Code Online (Sandbox Code Playgroud)
我试过了 :
Collection<TimePeriodCalc> collector = result.stream().collect(groupingBy(p -> p.getAtDate(), ....
Run Code Online (Sandbox Code Playgroud)
可以在代码中添加什么来选择多个属性?我正在考虑使用多个收集器,但实际上不知道如何操作.
我是Java 8的新手,希望了解这两种方案之间的区别.我知道一旦流被操作和消耗,然后流不能再次重用它将产生错误.
情景1:
List<String> title = Arrays.asList("Java8", "In", "Action");
Stream<String> s = title.stream();
s.forEach(System.out::println);
s.forEach(System.out::println); // THIS WILL GIVE ERROR - streams has been already operated and closed.
Run Code Online (Sandbox Code Playgroud)
当我运行这个时,我得到以下错误...这是公平的.
Java8
In
Action
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.sourceStageSpliterator(Unknown Source)
at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)
at com.test.Java8InAction.CH4.TraversableOnlyOnce.main(TraversableOnlyOnce.java:12)
Run Code Online (Sandbox Code Playgroud)
情景2:
// Filtering unique elements
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().forEach(System.out::println);
numbers.stream().filter(n -> n % 2 == 0).distinct().forEach(System.out::println);
numbers.stream().filter(n -> n % …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
interface Device {
// ...
boolean isDisconnected();
void reconnect();
}
interface Gateway {
// ...
List<Device> getDevices();
}
...
for (Gateway gateway : gateways) {
for(Device device : gateway.getDevices()){
if(device.isDisconnected()){
device.reconnect();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用Stream API重构代码.我的第一次尝试如下:
gateways
.stream()
.forEach(
gateway -> {
gateway
.getDevices()
.parallelStream()
.filter(device -> device.isDisconnected())
.forEach(device -> device.reconnect())
;
}
)
;
Run Code Online (Sandbox Code Playgroud)
我不喜欢它,经过一些修改后我最终得到了这段代码:
gateways
.parallelStream()
.map(gateway -> gateway.getDevices().parallelStream())
.map(stream -> stream.filter(device -> device.isDisconnected()))
.forEach(stream -> stream.forEach(device -> device.reconnect()))
;
Run Code Online (Sandbox Code Playgroud)
我的问题是是否有办法避免嵌套forEach.
我有这段代码
Coverage mainCoverage = illus.getLifes().stream()
.filter(Life::isIsmain)
.findFirst()
.orElseThrow(() -> new ServiceInvalidAgurmentGeneraliException(env.getProperty("MSG_002")))
.getCoverages()
.stream() // <==may cause null here if list coverage is null
.filter(Coverage::isMainplan)
.findFirst()
.orElseThrow(() -> new ServiceInvalidAgurmentGeneraliException(env.getProperty("MSG_002")));
Run Code Online (Sandbox Code Playgroud)
这完全可以正常工作,但我认为它有点乱,并没有涵盖所有null pointer exception可能的(见评论).
我尝试将此代码重构为
Coverage mainCoverage1 = illus.getLifes().stream()
.filter(Life::isIsmain)
.map(Life::getCoverages)
.filter(Coverage::isMainplan) //<== cannot filter from list coverage to one main coverage
...
Run Code Online (Sandbox Code Playgroud)
在我将生命映射到覆盖范围后,它似乎不再是一个覆盖列表.所以问题是如何将第一部分重构为null安全并且可能缩短它?
我有一个代码片段,我希望使用像lambdas/streams等Java 8功能更简洁可读.
基本上,有一个项目列表,每个项目都有一个错误列表.如果至少有一个项目至少有一个错误,则需要返回"失败".如果没有任何错误的项目,请返回"成功".
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
for (Item item : optionalItemList.get()) {
Optional<List<Error>> optionalErrorList = Optional.ofNullable((item.getErrors()));
if(optionalErrorList.isPresent())
if (!optionalErrorList.get().isEmpty()) {
return "failure";
}
}
return "success";
Run Code Online (Sandbox Code Playgroud) 我知道如何创建一个Map<T, List<U>>,使用Collectors.groupingBy:
Map<Key, List<Item>> listMap = items.stream().collect(Collectors.groupingBy(s->s.key));
如何修改要创建的代码Map<Key, Set<Item>>?或者我可以不使用它stream,因此必须使用for循环等手动创建它?
我在lambda vs方法参考上运行了一些JMH测试,看起来类似于:
IntStream......reduce(Integer::max)
vs.
IntSream.......reduce((i1, i2) -> Integer.max(i1, i2))
Run Code Online (Sandbox Code Playgroud)
我注意到的是,与Java中的lambda相比,方法引用的执行速度大约是lambda的5倍。当我在Java 11中运行测试时,两种方法的执行时间都与Java中方法引用的执行速度差不多。 8.因此,Java 11中的lambda和方法引用之间在性能上没有重大区别。
我的问题是:从Java 8到11进行了哪些改进以提高性能?我正在使用OpenJDK。
编辑我的基准:
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 1, jvmArgs = {"-XX:CompileThreshold=5000"})
@Warmup(iterations = 2)
public class FindMaxInt {
@Param({"10000", "1000000", "10000000"})
private int n;
private List<Integer> data;
@Setup
public void setup(){
data = createData();
}
@Benchmark
public void streamWithMethodReference(final Blackhole blackhole){
int max = data.stream().mapToInt(Integer::intValue).reduce(Integer.MIN_VALUE, Integer::max);
blackhole.consume(max);
}
@Benchmark
public void streamWithLambda(final Blackhole blackhole){
int max = data.stream().mapToInt(Integer::intValue).reduce(Integer.MIN_VALUE, (i1, i2) -> Integer.max(i1, i2));
blackhole.consume(max);
}
Run Code Online (Sandbox Code Playgroud) 有什么办法可以将以下操作作为一组流操作来执行,而不是显式地检查committedProducts 是否为空,然后返回默认列表,否则返回过滤后的列表?
public List<Product> getRecommendedProducts() {
List<Product> recommendedProducts
= this.newProducts
.stream()
.filter(isAvailable)
.collect(Collectors.toList());
if (recommendedProducts.isEmpty()) {
return DEFAULT_PRODUCTS;
}
return recommededProducts;
}
Run Code Online (Sandbox Code Playgroud) java ×10
java-stream ×10
java-8 ×8
collections ×2
optional ×2
foreach ×1
grouping ×1
hashmap ×1
jvm ×1
lambda ×1
performance ×1
set ×1