如何获取Java中同一个元素的最新记录?

How to get the latest records from the same element in Java?

我们如何才能在 Java 中做到这一点?我有一个 4 名员工对象,我看到他们的 ssn 相同,但我只想获取最新版本的此类记录。

public class MapDemo {
    public static void main(String[] args) {
        // Get the latest Schema version
        Employee employee = Employee.builder().firstName("John").lastname("Do").email("john.doe@gmail.com").ssn(12345).version(1).build();
        Employee employee1 = Employee.builder().firstName("John").lastname("Doe").email("john.doe@hotmail").ssn(12345).version(2).build();

        Employee employee2 = Employee.builder().firstName("Jane").lastname("K").email("jane.k@gmail").ssn(45678).version(20).build();
        Employee employee3 = Employee.builder().firstName("Jane").lastname("Kerr").email("jane.kerr@gmail").ssn(45678).version(28).build();

        List<Employee> employees = new ArrayList<>();
        employees.add(employee);
        employees.add(employee1);
        employees.add(employee2);
        employees.add(employee3);
        
        // I want latest version employee object here here its - employees1 and employees3
        
    }

Employee.java

@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class Employee {
    private String firstName;
    private String lastname;
    private String email;
    private int version;
    private int ssn;
}

我们可以这样做,但仍然可以mature/refactor。我会试试看,看看我能不能放另一个答案或者让它更成熟。

解法一:

Collection<Employee> values = employees.stream()
                .<Map<Integer, Employee>>collect(HashMap::new, (m, e) -> m.put(e.getSsn(), e), Map::putAll)
                .values();
        System.out.println(values);

我看到如下输出:

[Employee(firstName=John, lastname=Doe, email=john.doe@hotmail, version=2, ssn=12345), 
Employee(firstName=Jane, lastname=Kerr, email=jane.kerr@gmail, version=28, ssn=45678)]

一种方法是使用 Map.merge:

var ssnToEmployee = new HashMap<Integer, Employee>();
for (var emp: employees)
    ssnToEmployee.merge(emp.getSsn(), emp, (o, n) -> o.getSsn() > n.getSsn() ? o : n);
    
for (var emp: ssnToEmployee.values())
    System.out.println(emp);

同样,您可以使用流,特别是采用合并功能的 Collectors.toMap 版本:

var ssnToEmployee = employees.stream()
        .collect(Collectors.toMap(Employee::getSsn, e -> e, (o, n) -> o.getSsn() > n.getSsn() ? o : n);
        

(注意:以上不会以任何特定的排序顺序保留值。如果您想保留列表的原始顺序,可以改用 LinkedHashMap。)