2集合取出其中相同的不同的

如何用lambda表达式实现两个List实体类例如User集合,比较其中的id,然后相同的不同的抽离出来
@Data
public class User {
    private String name;
    private int age ;
    private String no;
    private int id;

    public User( int id,String name, String no, int age) {
        this.name = name;
        this.age = age;
        this.no = no;
        this.id = id;
    }
}


        List<User> listold = Arrays.asList(
                new User(1, "张三", "1", 23),
                new User(2, "李四", "2", 36),
                new User(3, "王五", "3", 29),
                new User(4, "赵六", "4", 29)
        );
        List<User> listnew = Arrays.asList(
                new User(1, "张三", "1", 28),
                new User(6, "狗蛋", "6", 20),
                new User(3, "王五", "3", 28),
                new User(7, "阿七", "7", 77)
        );
循环遍历两层进行对比可以实现感觉性能不高,不知如何用lambda表达式实现
我想要达到的结果:对比下两个集合然后取最listnew 中的与listold 相同的数据,listnew 中有listold 中没有的数据放入到两个新的集合
lista: {1, "张三", "1", 28),3},    {3,"王五", "3", 28}  新的 
listb:{6, "狗蛋", "6", 20},{7, "阿七", "7", 77}  之前没有的

         // 相同的
          List<User> together = listold.stream().filter(p->
                listnew.stream().map(User::getId).collect(Collectors.toList()).contains(p.getId()))
                .collect(Collectors.toList());
        // 不同的
        List<User> noTogether = listnew.stream().filter(p -> 
                !listold.stream().map(User::getId).collect(Collectors.toList()).contains(p.getId()))
                .collect(Collectors.toList());
//先listnew和listold去重取到 listb
List listb= listnew.stream().filter(item -> listold.stream().
noneMatch(e -> Objects.equals(item.getId(), e.getId()))).collect(Collectors.toList());
//再用b跟listnew去重取到a
 List lista = listnew.stream().filter(item -> listb.stream().
noneMatch(e -> Objects.equals(item.getId(), e.getId()))).collect(Collectors.toList());