Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从两个列表中排除非单个项目?_Java_Java Stream - Fatal编程技术网

Java 如何从两个列表中排除非单个项目?

Java 如何从两个列表中排除非单个项目?,java,java-stream,Java,Java Stream,如何使用来自两个列表的流来获取唯一实体的列表? 仅按用户名匹配 public class Entity { private String username; private String password; } var first = Arrays.asList( new Entity("user1", ""), new Entity("user2", &q

如何使用来自两个列表的流来获取唯一实体的列表? 仅按用户名匹配

public class Entity {   
    private String username;
    private String password;
}

    var first = Arrays.asList(
            new Entity("user1", ""),
            new Entity("user2", "")
            new Entity("user3", "pass3"),
            new Entity("user5", "pass5")
            
    );

    var second = Arrays.asList(
            new Entity("user1", "pass1"),
            new Entity("user2", "pass2"),
 
    );

    public static void foo(List<Entity> first, List<Entity> second) {
      List<Entity>result = Stream.of(first, second)
            .flatMap(List::stream)
            ? 
            ?
            .collect(Collectors.toList());
      }
公共类实体{
私有字符串用户名;
私有字符串密码;
}
var first=Arrays.asList(
新实体(“user1”,“user1”),
新实体(“user2”、“user2”)
新实体(“user3”、“pass3”),
新实体(“user5”、“pass5”)
);
var second=Arrays.asList(
新实体(“user1”、“pass1”),
新实体(“user2”、“pass2”),
);
公共静态void foo(先列表,后列表){
Listresult=Stream.of(第一,第二)
.flatMap(列表::流)
? 
?
.collect(Collectors.toList());
}

结果必须是包含实体(“user3”、“pass3”)和实体(“user5”、“pass5”)的列表。

您可以按用户名进行分组:

var groupedData = Stream.concat(list1.stream(), list2.stream())
                .collect(Collectors.groupingBy(Entity::getUsername));
然后筛选大小大于1的实体:

groupedData.values().stream()
            .filter(s -> s.size() == 1)
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
或者只有一条小溪:

Stream.concat(list1.stream(), list2.stream())
                .collect(Collectors.groupingBy(Entity::getUsername)).values().stream()
                .filter(s -> s.size() == 1)
                .flatMap(Collection::stream)
                .collect(Collectors.toList()); 

也许这不是最好的办法

 public static List<Entity> foo(List<Entity> first, List<Entity> second) {
    List<Entity> arr = new ArrayList<>();
    arr.addAll(first);
    arr.addAll(second);
    return arr
            .stream()
            .filter(entity -> (first.stream().map(Entity::getUsername).anyMatch(username -> username.equals(entity.getUsername())) &&
                    second.stream().map(Entity::getUsername).noneMatch(username -> username.equals(entity.getUsername()))) ||
                    (second.stream().map(Entity::getUsername).anyMatch(username -> username.equals(entity.getUsername())) &&
                            first.stream().map(Entity::getUsername).noneMatch(username -> username.equals(entity.getUsername()))))
            .collect(Collectors.toList());
}
公共静态列表foo(先列表,后列表){
List arr=new ArrayList();
arr.addAll(第一);
arr.addAll(第二);
返回arr
.stream()
.filter(entity->(first.stream().map(entity::getUsername).anyMatch(username->username.equals(entity.getUsername()))&&
second.stream().map(Entity::getUsername).noneMatch(username->username.equals(Entity.getUsername()))||
(second.stream().map(Entity::getUsername).anyMatch(username->username.equals(Entity.getUsername()))&&
first.stream().map(Entity::getUsername).noneMatch(username->username.equals(Entity.getUsername()))
.collect(Collectors.toList());
}
过滤器中的逻辑是“异或”,因为我们没有一种直接的方法来实现这一点,我们需要创建(条件1而不是条件2)或(条件2而不是条件1)的逻辑。

除了使用groupingBy,您还可以使用Collectors.toMap和merging(val1,val2)->null以排除要合并的元素,从而只留下单个元素:

List<Entity> result = Stream.concat(first.stream(), second.stream())
                            .collect(Collectors.toMap(Entity::getUsername, 
                                                      val -> val, (val1, val2) -> null))
                            .values().stream()
                            .collect(Collectors.toList());
List result=Stream.concat(first.Stream(),second.Stream())
.collect(Collectors.toMap)(实体::getUsername,
val->val,(val1,val2)->null)
.values().stream()
.collect(Collectors.toList());
lambda作为一种直接的解决方案
concat第一个列表实体的流不包含在第二个列表中,反之亦然

List<Entity> unique = Stream.concat(
    first.stream().filter(e -> ! second.contains( e )),
    second.stream().filter(e -> ! first.contains( e )) ).collect( toList() );
List unique=Stream.concat(
first.stream().filter(e->!second.contains(e)),
second.stream().filter(e->!first.contains(e)).collect(toList());

为什么要在代码中包含流构造?这似乎是最糟糕的实现方法。@daniu您能详细说明一下您的声明吗?为什么在这里使用流是一种糟糕的方法?@SergeiTonoian我需要部分收回它,但我会给出我的理由。关于这一点,你需要两个过程来完成——创建一个映射,然后过滤它(我没有想到SergeyAfinogenov的解决方案)。在一个(单一的)流中,这不是一件自然的事情。我认为这是一个很好的方法,感觉很粗糙,但有点独创性(而且很有效)。Thanx@daniu,我尝试使用所有的方法