我有一个用户定义的对象,称为员工,如下所示,并有两个不同的列表,其中包含员工对象。
在这两个不同的列表中,我需要根据对象中的名称字段找到唯一的对象。最终列表应仅包含一个名为c的对象。
请建议我如何使用java 8做到这一点?
import java.util.ArrayList;
import java.util.List;
class Employee{
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
public class UniqueObjects {
public static void main(String[] args) {
List<Employee> empOneList= new ArrayList<Employee>();
List<Employee> empTwoList= new ArrayList<Employee>();
Employee empOne= new Employee();
empOne.setName("a");
empOne.setAge("23");
empOneList.add(empOne);
Employee emptwo= new Employee();
emptwo.setName("b");
emptwo.setAge("24");
empOneList.add(emptwo);
Employee em= new Employee();
em.setName("a");
em.setAge("23");
empTwoList.add(em);
Employee emp1= new Employee();
emp1.setName("d");
emp1.setAge("24");
empTwoList.add(emp1);
}
}
如果我正确理解了你的问题,你正在寻找只出现在其中一个列表中但不同时出现在两个列表中的元素。这称为析取并集。有一种非常简单的方法可以使用Collection.removeAll()
检索它:
public static <T> Set<T> getDisjunctiveUnion(Set<T> set1, Set<T> set2)
{
Collection<T> copy1 = new HashSet<>(set1);
Collection<T> copy2 = new HashSet<>(set2);
copy1.removeAll(set2);
copy2.removeAll(set1);
copy1.addAll(copy2);
return copy1;
}
请注意,这需要基于名称为员工实现等于和哈希代码(您的IDE将为您做到这一点):
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Employee other = (Employee) obj;
if (name == null && other.name != null) return false;
else if (!name.equals(other.name)) return false;
return true;
}
如果不想实现这些方法,可以使用新方法集合。removeIf():
copy1.removeIf(emp1 -> set2.stream().anyMatch(emp2 -> emp2.getName().equals(emp1.getName())));
copy2.removeIf(emp2 -> set1.stream().anyMatch(emp1 -> emp1.getName().equals(emp2.getName())));
或者,您使用stream来过滤集合而不是复制/删除(小心使用noneMatch
而不是anyMatch
):
Collection<Employee> disjunctiveUnion = new HashSet<>();
set1.stream()
.filter(emp1 -> set2.stream().noneMatch(emp2 -> emp2.getName().equals(emp1.getName())))
.forEach(disjunctiveUnion::add);
set2.stream()
.filter(emp2 -> set1.stream().noneMatch(emp1 -> emp1.getName().equals(emp2.getName())))
.forEach(disjunctiveUnion::add);
return disjunctiveUnion;
要根据名称字段查找唯一对象,可以使用以下代码:
Map<String, List<Employee>> employeeMap = Stream.concat(empOneList.stream(), empTwoList.stream())
.collect(Collectors.groupingBy(Employee::getName, Collectors.toList()));
>
Collection<List<Employee>> employeesWithUniqueName =
Maps.filterValues(employeeMap, empList -> empList.size() == 1).values();
使用流API
Collection<Employee> employeesWithUniqueName =
employeeMap.values().stream().filter(empList -> empList.size() == 1)
.flatMap(List::stream)
.collect(Collectors.toList());
我想你要问的是,如何在两个列表中找到一个有名字的员工。如果是这种情况,那么最简单的事情就是流式处理这两个列表,并筛选出唯一的员工:
Optional<Employee> employee = Stream.concat(list1.stream(), list2.stream())
.filter(e -> e.getName().equals(name)).findAny();
如果您想要两个列表中具有名称的对象,那么:
List<Employee> employees = Stream.concat(list1.stream(), list2.stream))
.filter(e -> e.getName().equals(name)).collect(Collectors.toList());
我在下面使用JDK7进行了探讨
我有两张单子。人类名单和超人名单。我想从这两个列表中创建一个列表,确保如果一个人是超人,那么它只会在使用Java8的列表中出现一次。有什么好办法吗?更新:这些是不同的类,即两者都不扩展另一个。我希望最后的名单是超人。如果一个人已经是超人了,我们就忽略了这个人类对象。如果人不是超人,我们就把人的物体变成超人的物体。理想情况下,我希望在最后按年龄对他们进行排序,这样我就可以得到一个按日期降序排列的超人
我应该如何删除列表中所有不符合条件的子对象并获得新的列表。
问题内容: 我有以下Java6和Java8代码: Java8中有什么方法可以使用Lambda以更简洁的方式处理前一个问题? 问题答案: 流绑定到给定的可迭代/集合,因此您不能真正地“并行”迭代两个集合。 一种解决方法是创建索引流,但不一定比for循环有所改进。流版本可能如下所示:
问题内容: 我有一个看起来像这样的列表列表: 删除重复列表的最佳方法是什么?使用上面的示例,我正在寻找会产生这种情况的代码: 我最初以为我可以使用,但这似乎不适用于列表列表。我还看到了一个使用的示例,但是代码对我来说并不完全清楚。谢谢您的帮助! 问题答案: uniq_animal_groups = set(map(tuple, animal_groups)) 尽管您将得到一组元组而不是一组列表,但
我有一个学生名单a和学生名单B。 学生对象包含如下字段:否、年龄、城市、出生日期、工资 我的列表A包含这些对象 我的列表B包含这些对象 我想做的是提取ListA有但listB没有的学生对象,以及ListA和listB有但薪水不同的学生对象(如否、年龄、城市)。我还想写工资差异。 我想在java 8中使用流api。首先,我想将students对象提取到列表中,但我现在可以提取常见的student对象