6

I have a scenario to sort the objects based on timestamp. The classes are as follows:

class Employee 
{
    private String name;
    private List<Address> addresses;

    //...
    //Getters and setters for all fields
}

public class Address
{
    private String city;
    private Timestamp startDate;
    private Timestamp endDate;
    private String typeOfResidence;

    //...
    //Getters and setters for all the fields
}

For an employee, there are 2 possibilities 1. it will have a list of address. 2. the list of address can be null

The address class has a field typeOfResidence which can have values such as Residence, Office, ForeignHome.

Each Employee can have list of address, one address will be Residential, other Office and so on. There can be multiple Residential addresses but only one Office address.

I want to sort the list of employees based on startDate of Address whose typeOfResidence=Office.

I have written the following code:

private void sortEmployeeListBasedOnStartDate(List<Employee> employeeList)
{
    Comparator<Address> byTimeStamp = Comparator.comparing(
        Address::getStarteDate,
        (ts1, ts2) -> ts1.toGregorianCalendar().compareTo(ts2.toGregorianCalendar())
    );

    employeeList.stream()
        .map(x -> getLatestAddressByType(x, "Office"))
        .filter(y -> y!=null)
        .sorted(byTimeStamp.reversed())
        .collect(Collectors.toList());
}

public Address getLatestAddressByType(Employee employee, String type)
{
    if(role != null && brokerageManagedProposalType != null)
    {
         return getUserAddress(employee).stream()
            .filter(address-> address.getTypeOfResidence().equals(type))
            .findFirst()
            .orElse(null);
    }
    return null;
}

public List<Address> getUserAddress(Employee employee)
{
    if (!NullChecker.isNull(employee) && !NullChecker.isNull(employee.getAddress()))
    {
        return employee.getAddress();
    }
    return Collections.emptyList();
}

Somehow this does not seem to be working. The employees are not sorted. Please help me to make it working.

3 Answers 3

5

Your sortEmployeeListBasedOnStartDate method doesn't mutate the input List<Employee>. It creates a new sorted List<Address>, which you do nothing with.

If you want a sorted List<Employee>, you shouldn't be mapping the Employees to Addresses. You should produce a sorted List<Employee> and return that List.

Something like this should do:

private List<Employee> sortEmployeeListBasedOnStartDate(List<Employee> employeeList)
{
    Comparator<Address> byTimeStamp = Comparator.comparing(
        Address::getStarteDate,
        (ts1, ts2) -> ts1.toGregorianCalendar().compareTo(ts2.toGregorianCalendar())
    );

    return employeeList
        .stream()
        .sorted((e1,e2)->byTimeStamp.compare(getLatestAddressByType(e2, "Office"),getLatestAddressByType(e1, "Office")))
        .collect(Collectors.toList());
}

You might have to add some handling for the case where getLatestAddressByType() returns null:

    return employeeList
        .stream()
        .filter(e->getLatestAddressByType(e, "Office") != null)
        .sorted((e1,e2)->byTimeStamp.compare(getLatestAddressByType(e2, "Office"),getLatestAddressByType(e1, "Office")))
        .collect(Collectors.toList());
Sign up to request clarification or add additional context in comments.

Comments

3

If you want in-place sorting, you can use Collections.sort instead of streams.

Collections.sort(employeeList, 
    (e1,e2) -> byTimeStamp.compare(
        getLatestAddressByType(e2, "Office"),
        getLatestAddressByType(e1, "Office") );

Similarly, the null-filtering issue can be solved in-place as follows:

employeeList.removeIf(e -> getLatestAddressByType(e, "Office") == null);

(btw, getLatestAddressByType should probably be an instance method of Employee)

3 Comments

Is there any way that null check and sorting can be combined in a single statement?
@azaveri7 Yes, you can plug the second statement as the first argument of "sort", but I would advise against it for readability.
Thanks a lot Marco.
1

Your problem is here:

employeeList.stream()
    .map(x -> getLatestAddressByType(x, "Office"))
    .filter(y -> y!=null)
    .sorted(byTimeStamp.reversed())
    .collect(Collectors.toList());

This is not an in-place sort. The values in employeeList remain exactly the same. collect is creating a new List instance which is never assigned to a variable or returned - the instance is simply created and then immediately illegible for garbage collection.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.