标签: java-stream

如何总结对象流的数字属性?

我尝试总结对象流的双重属性:

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)

如何计算对象流的汇总属性?

java java-stream

2
推荐指数
1
解决办法
85
查看次数

使用 Java Streams 返回出现单词的句子的计数和列表

我被困在试图找出每个单词出现的句子中。该条目将是一个句子列表

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 新手

java lambda java-8 java-stream

2
推荐指数
1
解决办法
93
查看次数

为什么这个 lambda 可以在这里使用,在 Arrays.sort() 中需要一个比较器

我是 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它与书中所说的不同。

java lambda functional-programming java-stream

2
推荐指数
1
解决办法
55
查看次数

在单循环中以声明方式单独按多个字段进行 Java 流分组

我用谷歌搜索了它,但我主要找到了按聚合字段分组或更改流响应的案例,但不是以下场景:

我有一个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)

java declarative-programming java-stream groupingby

2
推荐指数
1
解决办法
69
查看次数

在流中按条件抛出异常

如何过滤流表达式以抛出异常?

我有检查列表元素总和的功能,如果总和大于 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条件?

java java-stream

2
推荐指数
1
解决办法
82
查看次数

为什么没有 OptionalDouble orElseNull() 或更好的解决方案

我有一个计算平均成本的流,代码看起来像这样

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))。

我缺少原因或更好的解决方案吗?

java optional java-stream

2
推荐指数
1
解决办法
141
查看次数

带有流和布尔结果的 Java Optional.ofNullable(Object[] objects)

我正在尝试实现这样的实用方法

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)

我觉得很愚蠢,但我的问题是:有没有办法实现这样的实用方法,使用 …

java java-stream

2
推荐指数
1
解决办法
101
查看次数

Java Streams 将 Streams 与供应商连接起来,然后是不同的(惰性求值行为)

我有一个像这样的简单代码

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)

java distinct-values java-8 java-stream

2
推荐指数
1
解决办法
91
查看次数

如果条件不满足,如何跳过映射元素

假设我有以下内容

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 个元素。

关于如何添加该行为的任何建议?

java java-stream

2
推荐指数
1
解决办法
59
查看次数

为什么 Collectors.toUnmodifiableList 使用中间累加器的类型检查?

我看到以下代码(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我们提供了类的最具体的方法句柄,而不是接口。最后一个代码假设累加器实例将作为 …

java java-stream collectors

2
推荐指数
1
解决办法
58
查看次数