标签: java-stream

如何有条件地修改 Java 8 流 API 中的 Map?

我正在尝试Map根据条件逻辑和挣扎修改 a的键。我是 Java 8 流 API 的新手。假设我有一张这样的地图:

Map<String, String> map = new HashMap<>();

map.put("PLACEHOLDER", "some_data1");
map.put("Google", "some_data2");
map.put("Facebook", "some_data3");
map.put("Microsoft", "some_data4");
Run Code Online (Sandbox Code Playgroud)

当我想做的是PLACEHOLDER根据布尔条件找到引用并有条件地将该键更改为其他内容。我觉得它应该是什么样的下方,但这并不甚至编译过程的。

boolean condition = foo();

map = map.entrySet().stream().filter(entry -> "PLACEHOLDER".equals(entry.getKey()))
        .map(key -> {
            if (condition) {
                return "Apple";
            } else {
                return "Netflix";
            }
        }).collect(Collectors.toMap(e -> e.getKey(), Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)

我发现这个问题让我觉得也许我不能用 Java 8 流 API 来做到这一点。希望有比我更擅长的人知道如何做到这一点。如果你想玩它,Ideone 链接。

java lambda java-8 java-stream

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

为什么我无法在 java Stream 的代码中使用收集器?

import static java.util.stream.Collectors.*;
import java.util.*;
import java.lang.*;
//import java.util.Collections;
public class HelloWorld{

 public static void main(String []args){
    System.out.println("Hello World");
    List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
    List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

/tmp/java_tdo3eB/HelloWorld.java:10: error: cannot find symbol
    List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
                                                                                         ^
  symbol:   variable Collectors
  location: class HelloWorld
 1 error
Run Code Online (Sandbox Code Playgroud)

所以我问的是为什么我不能使用收集器,因为我也导入了那个类

java java-stream

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

通过 Java Streams 时 AssertThrows 不会抛出异常

所以我正在编写单元测试,其中我正在测试将用户列入黑名单和取消黑名单的能力(这是我代码中的一个功能,它本身工作正常)。

这是一个按预期工作的示例命令:

assertThrows(ExecutionException.class, () -> onlineStore.lookup("533"));
Run Code Online (Sandbox Code Playgroud)

如果我将用户“533”列入黑名单,然后运行上面的命令,它工作正常,因为 anExecutionException被引发(因为您正在尝试查找被列入黑名单的用户)。类似地,如果我没有将用户“533”列入黑名单但仍然运行上述命令,则测试将失败,这也是出于类似原因的预期(即,由于您未获取列入黑名单的用户,因此现在不会抛出异常)。

但是,如果我有一个List用户 ID userIds(用户“533”现在是其中的一部分)并且我将它们全部列入黑名单(我知道功能正常),然后运行以下命令:

userIds.stream().map(id -> assertDoesNotThrow(() -> onlineStore.lookup(id)));
Run Code Online (Sandbox Code Playgroud)

...测试通过,即使通过它也应该失败。为什么 ?因为现在所有用户都被列入黑名单,所以在获取这些用户时,ExecutionExceptions应该已经抛出..

如果我现在用以下任一命令替换上面的流命令,它们会按预期工作:

assertThrows(ExecutionException.class, () -> onlineStore.lookup("533"));

assertDoesNotThrow(() -> onlineStore.lookup("533"));
Run Code Online (Sandbox Code Playgroud)

所以这一切让我相信,出于某种原因,在通过 Java Streams 时,throwsExecutionExceptions不会被捕获。

这种行为有什么解释吗?

java junit unit-testing assert java-stream

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

自定义收集器仅当流不是空后缀时才在分隔符、后缀和前缀上加入流

我有一个字符串流:

Stream<String> stream = ...;

我想使用创建一个字符串

stream.collect(Collectors.joining(',', '[', ']'))

如果流不包含任何元素,我只想返回“无字符串”。

我注意到该String java.util.stream.Stream.collect(Collector<? super String, ?, String> collector) 方法采用 java.util.stream.Collector<T, A, R> 类型的参数

对于我的项目,我在很多地方都需要这个功能,所以我需要一个实现Collector接口的类。

我知道这可以通过 Stream to a List 然后检查 List.size() == 0 来完成?如果需要,然后再次将列表转换为流。

List<String> list = stream.collect(Collectors.toList());

if (list.size() == 0) {
    return "No Strings";
}
return list.stream().collect(Collectors.joining(",", "[", "]"));`
Run Code Online (Sandbox Code Playgroud)

这就是我想要发生的

List emptyList<String> = new ArrayList<>; System.out.println(emptyList.stream().collect(Collectors.joining(",", "[", "]")));

输出

[]

我想要的输出

No Strings

java java-stream collectors

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

如何比较两个地图并检索两个地图中出现的值的键?

newPropertiesFile.keySet().parallelStream()
    .filter(value -> oldPropertiesFile.keySet().parallelStream()
            .filter(entry -> oldPropertiesFile.get(entry).toString().equals(newPropertiesFile.get(value).toString()))
            .filter(values -> !values.equals(value)).count() > 0)
    .collect(Collectors.toMap(entryKey -> (String) entryKey, entryKey -> newPropertiesFile.get(entryKey).toString()));
Run Code Online (Sandbox Code Playgroud)

例如,我有mapA = {(1,'a'),(2,'b'),(3,'c')}并mapB = {(5,'a'),(6,'d'),(7,'c')} 比较了两个地图的 valueList,值'a'和'c'inmapA出现在mapB,它们的键是5和7分别。

因此我需要的 o/p:
5,7

我已经完成了上述操作并获得了所需的输出。但是复杂度在 O(n^2) 上太高了。有什么优化的方法吗?

一个更简单的例子:

mapA.keySet().parallelStream()
    .filter(v->mapB.keySet().parallelStream()
            .filter(e->mapB.get(v).equals(mapA.get(v)))
            .filter(v->!v.equals(v)).count()>0)
    .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

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

使用 Optional 避免 NPE

我试图避免检查(if ... != null)或try{...}catch(NullPointerException e) {...}

让我们举个例子来理解我的问题:

我有一个class Park包含List<Car> 我有一个class Car包含一个Motor object 我有一个class Motor包含一个Name String值

我想从我的 Park 类中返回第一个字符串电机名称:

我想避免:

if (park != null) {
    if (park.getCars() != null) {
        for (Car car : park.getCars() {
              if (car.getMotor() != null) {
                  return car.getMotor().getName();
Run Code Online (Sandbox Code Playgroud)

我在想这样的事情:

Optional.ofNullable(park).map(Park::getCars).ifPresent(cars -> {
    return cars.stream().map(Car::getMotor).map(Motor::getName).findFirst().orElse(null);
});
Run Code Online (Sandbox Code Playgroud)

但它不编译。有任何想法吗 ??

java optional java-8 java-stream

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

Java 中的 lambda 表达式 ClassCastException

我正在尝试在 Java 8 中学习流媒体。以下是我的代码:

主程序

public class Main {
    public static void main(String[] args) {

        Person person = new Person("FirstName", "LastName");
        List<Person> personList = new ArrayList<>();
        personList.add(person);

        Place place = new Place("name", "country");
        List<Place> placeList = new ArrayList<>();
        placeList.add(place);


        List<List<Object>> objects = new ArrayList<>();
        objects.add(Collections.singletonList(personList));
        objects.add(Collections.singletonList(placeList));

        List<Object> persons = objects.get(0);
        List<String> firstNames = persons.stream()
                .map(o -> ((Person)o).getFirstName())
                .collect(Collectors.toList());

        firstNames.forEach(System.out::println);
    }
}
Run Code Online (Sandbox Code Playgroud)

人.java

@Data
public class Person {
    String firstName;
    String lastName;

    public Person(String firstName, String lastName) {
        setFirstName(firstName);
        setLastName(lastName);
    } …
Run Code Online (Sandbox Code Playgroud)

java casting java-8 java-stream

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

将流映射到原始索引列表

我想对流进行排序,然后将其元素收集为各自的原始索引。

例如:

List<String> l = Arrays.asList("a", "b", "d", "c");
List<Integer> i = l.stream().sorted(Comparator.comparing(s -> s)).??? // what to do here?
// i = [0, 1, 3, 2]
Run Code Online (Sandbox Code Playgroud)

java java-stream

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

Java 8:将 List&lt;List&lt;List&lt;Product&gt;&gt; 合并为一个列表

我有 3 个列表,List<List<List<Product>>我想将它们合并为一个。我已经阅读了几篇 SO 文章,但我仍然不确定如何继续。到目前为止我有

allProducts.stream()
    .flatMap(List::Stream)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但这只会合并两个列表,对吗?在该语句中合并所有三个的最佳方法是什么?我见过reduce()用过,但我不知道怎么写。我需要获得Product.

java java-8 java-stream

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

使用 Streams 比较和组合两个不同类型的列表

我有以下课程:

public class Role {

    private Integer id;
    private String name;
    private String description;

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)
public class UserRole {

    private Integer id;
    private User user;
    private Role role;

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)
public class RoleCheckbox {

    private Role role;
    private Boolean checked;

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

现在在我的服务类中,我得到了 Role 和 UserRole 对象的列表。角色列表包含所有可用角色,用户角色列表包含分配给特定用户的角色。

我想比较这两个列表并创建一个 RoleCheckbox 对象列表。因此,新创建的列表应包含所有角色和“已检查”字段,其值取决于用户的角色。

我已经解决了如下:

this.roleCheckboxes = new ArrayList<RoleCheckbox>();
for(Role role : roles) {
    Boolean checked = false;
    for (UserRole userRole : user.getUserRoles()) {
        if(userRole.getRole() == role) …
Run Code Online (Sandbox Code Playgroud)

java collections for-loop java-8 java-stream

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