我尝试总结对象流的双重属性:
items.collect(Collectors.summingDouble(double::doubleValue)
Run Code Online (Sandbox Code Playgroud)
但我无法解析方法“doubleValue”
这是项目定义:
流项目= ...;
这是 Item 对象定义:
public class Item {
private double price;
private Date date;
private String name;
}
Run Code Online (Sandbox Code Playgroud)
如何计算对象流的汇总属性?
我被困在试图找出每个单词出现的句子中。该条目将是一个句子列表
Question, what kind of wine is best?
White wine.
A question
Run Code Online (Sandbox Code Playgroud)
输出将是
// format would be: word:{count: sentence1, sentence2,...}
a:{1:3}
wine:{2:1,2}
best:{1:1}
is:{1:1}
kind:{1:1}
of:{1:1}
question:{2:1,3}
what:{1:1}
white:{1:2}
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所得到的:
static void getFrequency(List<String> inputLines) {
List<String> list = inputLines.stream()
.map(w -> w.split("[^a-zA-Z0-9]+"))
.flatMap(Arrays::stream)
.map(String::toLowerCase)
.collect(Collectors.toList());
Map<String, Integer> wordCounter = list.stream()
.collect(Collectors.toMap(w -> w, w -> 1, Integer::sum));
}
Run Code Online (Sandbox Code Playgroud)
有了这个,我只能得到每个单词出现在所有句子中的次数,但我还需要获得该单词出现的句子列表。看起来也许是为了获取我可以使用的句子的 id IntStream.range,如下所示:
IntStream.range(1, inputLines.size())
.mapToObj(i -> inputLines.get(i));
Run Code Online (Sandbox Code Playgroud)
但我不确定这是否是最好的方法,我是 Java 新手
我是 Lambda 的新手,这是教科书(简而言之 java)所说的内容:
只有某些类型才有资格成为 lambda 的目标。目标类型也称为功能接口,它们必须:
- 成为接口
- 只有一种非默认方法(但可能有其他默认方法)
这本书给了我一个例子:
File dir =new File("/src");
String[] fileList =dir.list((d,fName)->fName.endWith(".java"))
Run Code Online (Sandbox Code Playgroud)
我知道这个 lambda 会转换成一个FilenameFilter接口,@FunctionalInterface它确实与书中的描述相符
但是我可以在这里使用 lambda 来sort()期望收到一个Comparator
int n =12;
Function<String,String[]> f = (s) -> {
String[] ans = new String[n];();
for (int i = 0; i < n; i++) {
ans[i] = s;
}
return ans;};
Arrays.sort(f.apply("colin"),(String s1 ,String s2)->{
return s1.length() - s2.length();});
Run Code Online (Sandbox Code Playgroud)
我查看了它的源代码,发现Comparator是一个@FunctionInterface

但它有两个非默认方法compare和。equals它与书中所说的不同。
我用谷歌搜索了它,但我主要找到了按聚合字段分组或更改流响应的案例,但不是以下场景:
我有一个User带有字段category和marketingChannel.
我必须以声明式风格编写一个方法,该方法接受用户列表并基于category和基于marketingChannel单独(即 not groupingBy(... ,groupingBy(..)))计算用户
。
我无法在一个循环中完成。这是我必须达到的目标。
我编码了一些方法如下:
import java.util.*;
import java.util.stream.*;
public class Main
{
public static void main(String[] args) {
List<User> users = User.createDemoList();
imperative(users);
declerativeMultipleLoop(users);
declerativeMultipleColumn(users);
}
public static void imperative(List<User> users){
Map<String, Integer> categoryMap = new HashMap<>();
Map<String, Integer> channelMap = new HashMap<>();
for(User user : users){
Integer value = categoryMap.getOrDefault(user.getCategory(), 0);
categoryMap.put(user.getCategory(), value+1);
value = channelMap.getOrDefault(user.getMarketingChannel(), 0);
channelMap.put(user.getMarketingChannel(), value+1);
}
System.out.println("imperative");
System.out.println(categoryMap);
System.out.println(channelMap); …Run Code Online (Sandbox Code Playgroud) 如何过滤流表达式以抛出异常?
我有检查列表元素总和的功能,如果总和大于 1 -> 抛出异常
Double sum = list.stream().map(element::getNumber).reduce(0.0,Double::sum);
if(sum>1){
throw new Exception("message);
}
Run Code Online (Sandbox Code Playgroud)
是否可以向if流表达式添加条件以摆脱附加if条件?
我有一个计算平均成本的流,代码看起来像这样
private Double calculateAverageCost(List<Item> items) {
return items.stream()
.mapToDouble(item -> item.cost)
.filter(cost -> cost > 0) // Ignore zero cost items
.average()
. // Something here to convert an OptionalDouble to value or null
}
Run Code Online (Sandbox Code Playgroud)
我需要返回值或null没有值的方法(例如,当所有成本为零时)。我的问题是不存在orElseNull的方法OptionalDouble做转换。我可以在另一个步骤中完成,例如
private Double calculateAverageCost(List<Item> items) {
final OptionalDouble average = items.stream()
.mapToDouble(item -> item.cost)
.filter(cost -> cost > 0) // Ignore zero cost items
.average();
return average.isPresent() ? average.getAsDouble() : null;
}
Run Code Online (Sandbox Code Playgroud)
我意识到这是一个“原始”流,我的方法返回盒装,Double但看起来这可能会有所帮助,类似于 ( Optional.empty().orElseGet(null))。
我缺少原因或更好的解决方案吗?
我正在尝试实现这样的实用方法
boolean allNotNull( LocalDate... objects )
Run Code Online (Sandbox Code Playgroud)
以便它true仅在有元素(objectsvararg 不是null)并且其中没有null元素的情况下返回。此外,我想使用 Streams 和 Optionals 以函数式风格实现它,而不涉及任何 if 语句。
解决方案似乎很明显:
private static boolean allNotNull( LocalDate... objects )
{
boolean allNotNull = Optional.ofNullable( objects )
.stream()
.flatMap( Arrays::stream )
.noneMatch( Objects::isNull );
return allNotNull;
}
Run Code Online (Sandbox Code Playgroud)
但true如果objectsvararg 是 ,它总是返回null。究其原因必须是Optional.stream()回报Stream.empty()这个情况下它总是返回true尽管断言:
Assert.assertTrue( Stream.empty().noneMatch( o -> true )); //always true
Assert.assertTrue( Stream.empty().noneMatch( o -> false )); //also always true
Run Code Online (Sandbox Code Playgroud)
我觉得很愚蠢,但我的问题是:有没有办法实现这样的实用方法,使用 …
我有一个像这样的简单代码
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamSupplierVersusConcat {
public static void main(String[] args) {
final StreamSupplierVersusConcat clazz = new StreamSupplierVersusConcat();
clazz.doConcat();
}
private void doConcat(){
System.out.println(Stream.concat(buildStreamFromRange(0,1000).get()
,buildStreamFromRange(1000,2000).get())
.anyMatch("1"::equals));
}
private Supplier<Stream<String>>buildStreamFromRange(final int start,final int end){
return ()->IntStream.range(start, end)
.mapToObj(i->{
System.out.println("index At: "+i);
return String.valueOf(i);
});
}
}
Run Code Online (Sandbox Code Playgroud)
我知道 concat 是懒惰的,所以当我运行代码时,我看到它只生成了 2 个很棒的值,但知道 distinct 是一个有状态的操作,我认为将该方法放在 Stream 管道上它会生成所有值,然后做 anyMatch 方法,但如果我这样说
private void doConcat(){
System.out.println(Stream.concat(buildStreamFromRange(0,1000).get()
,buildStreamFromRange(1000,2000).get())
.distinct()//ARE ALL THE VALUES GENERATED NOT REQUIRED HERE???
.anyMatch("1"::equals));
}
Run Code Online (Sandbox Code Playgroud)
但是有了不同的和没有它,我得到了相同的回应。
index At: 0 …Run Code Online (Sandbox Code Playgroud) 假设我有以下内容
public class UserEntity{
String id;
List<String> relatedEntity;
}
public class EmployeeEntity{
String id;
String name;
Boolean isActive;
List<String> relatedEntityDetails;
}
Run Code Online (Sandbox Code Playgroud)
现在有一个 UserEntity 列表,我必须映射到一个 EmployeeEntity 列表:
private List<EmployeeEntity> getEmployees(List<UserEntity> users)
return users.stream()
.filter(x-> !x.getRelatedEntity().isEmpty())
.map(this::mapToEmployee)
.collect(Collectors.toList());
}
private EmployeeEntity mapToEmployee(UserEntity userEntity){
// retrieve EmployeeEntity from DB and perform a validations like
// employeeEntity.isActive = true
return employeeEntity;
}
Run Code Online (Sandbox Code Playgroud)
现在,一切正常,但是我需要处理当 EmployeeEntity 不存在于 db 或 isActive = false 时的场景,在这些场景中,应该跳过 map(),所以如果有 3 个元素的列表 UserEntity 和其中一个用户,一名员工不活跃,那么返回的 List 应该只有 2 个元素。
关于如何添加该行为的任何建议?
我看到以下代码(JDK 16、JDK 17):
public static <T>
Collector<T, ?, List<T>> toUnmodifiableList() {
return new CollectorImpl<>(ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
list -> {
if (list.getClass() == ArrayList.class) { // ensure it's trusted
return SharedSecrets.getJavaUtilCollectionAccess()
.listFromTrustedArray(list.toArray());
} else {
throw new IllegalArgumentException();
}
},
CH_NOID);
}
Run Code Online (Sandbox Code Playgroud)
使用if (list.getClass() == ArrayList.class) {检查有什么意义?为什么不简单地使这段代码像这样简单
return new CollectorImpl<>(ArrayList::new, ArrayList::add,
(left, right) -> { left.addAll(right); return left; },
list -> SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(list.toArray()),
CH_NOID);
Run Code Online (Sandbox Code Playgroud)
通过替换为List::add,ArrayList::add我们提供了类的最具体的方法句柄,而不是接口。最后一个代码假设累加器实例将作为 …