is there a faster way to extract unique values from object collection?

collections, java

Solution

If you want to get or count the distinct areas in the employee list, you can use a set of strings. I'm changing the variable names to match Java standards. You can get the count afterwards. ideally, these would be lazy methods.

Imperative Code

public Set<String> areas(final List<Employee> employees) {
    Set<String> areas = new HashSet<>();
    for(final Employee employee: employees) {
        areas.add(employee.getArea());
    }
    return areas;
}

Functional Code (Google Guava)

public Set<String> areas(final List<Employee> employees) {
    return Sets.newHashSet(
        Lists.transform(employees, new Function<Employee, String>() {
            public String apply(Employee e) {
                return e.getArea();
            }
        }));
}

Lambdas (Java 8)

public Set<String> areas(final List<Employee> employees) {
    return new HashSet<String>(employees.map(e => e.getArea()));
}

Problem

I have a method to extract the values from an object collection that is a employee information: ``` public class Employee { public String AREA; public String EMPLOYEE_ID; public String EMPLOYEE_NAME; } ``` I'd like to get all the distinct Areas I did what I thought would be the easier, just check if the ArrayList contains the value, if not the add it, it takes 187ms to complete, : ``` long startTime = System.currentTimeMillis(); ArrayList<String> distinct_areas = new ArrayList<String>(); for (int i = 0; i < this.employeeTress.length; i++) { if (!distinct_areas.contains(this.employeeTress[i].AREA)) distinct_areas.add(this.employeeTress[i].AREA); } String[] unique = new String[distinct_areas.size()]; distinct_areas.toArray(unique); long endTime = System.currentTimeMillis(); System.out.println("Total execution time: " + (endTime - startTime) + "ms"); ``` then I thought to do it differently to see if it gets faster, sorting the array then check only the last item if its different then add it, and its a little bit faster, it takes 121ms to complete: ``` startTime = System.currentTimeMillis(); String[] vs = new String[this.employeeTress.length]; for (int i = 0; i < this.employeeTress.length; i++) { vs[i] = this.employeeTress[i].AREA; } Arrays.sort(vs); ArrayList<String> vsunique = new ArrayList<String>(); vsunique.add(vs[0]); for (int i = 0; i < vs.length; i++) { if (!vsunique.get(vsunique.size()-1).equals(vs[i])) { vsunique.add(vs[i]); } } String[] uni = new String[vsunique.size()]; vsunique.toArray(uni); endTime = System.currentTimeMillis(); System.out.println("Total execution time: " + (endTime - startTime) + "ms"); ``` I'm new to Java I'd like to know a better way to do this. *Note, this code should work in android gingerbread API LVL 10 regards.

Original source

Related problems