3

我有一种方法可以从作为员工信息的对象集合中提取值:

public class Employee
{
    public String AREA;
    public String EMPLOYEE_ID;
    public String EMPLOYEE_NAME;
}

我想获得我认为更容易的所有不同区域,只需检查 ArrayList 是否包含该值,如果不是添加它,则需要 187 毫秒才能完成,:

    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");

然后我想用不同的方法来看看它是否变得更快,对数组进行排序,然后只检查最后一项是否不同,然后添加它,它的速度有点快,需要 121 毫秒才能完成:

    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");

我是 Java 新手,我想知道一种更好的方法来做到这一点。*注意,此代码应在 android 姜饼 API LVL 10 中工作。

4

4 回答 4

10

如果要获取或计算员工列表中的不同区域,可以使用一组字符串。我正在更改变量名称以匹配 Java 标准。之后你可以得到计数。理想情况下,这些将是惰性方法。

命令式代码

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

功能代码(谷歌番石榴)

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();
            }
        }));
}

Lambda (Java 8)

public Set<String> areas(final List<Employee> employees) {
    return new HashSet<String>(employees.map(e => e.getArea()));
}
于 2013-07-31T15:23:14.940 回答
2

将所有员工插入HashSet. 从 的定义来看Set,它们都是唯一的。

Set<Employee> unique = new HashSet<Employee>(Arrays.asList(employeeTress));
// unique.toArray() if needed

如果您希望Employee对象在具有相同 时被视为相等,则AREA需要正确覆盖类中的equals()方法Employee

于 2013-07-31T14:29:35.437 回答
2

Set正如其他人已经说过的那样,您可以使用 a来执行此操作,但是如果您希望项目在它们相同时被视为相等,AREA那么您需要覆盖对象中的equals方法Employee以使其与其他基于该方法的对象进行比较多变的。

在覆盖 equals 方法之前,您需要知道一些事情。这里有一个讨论: 在Java中覆盖equals和hashCode时应该考虑哪些问题?

于 2013-07-31T14:31:48.653 回答
1

只需使用 HashSet,它只会向 HashSet 添加唯一元素

HashSet的objectOfHashSet.add(Object)函数将返回true on successful对象的加法,

Set<Employee> hs = new HashSet<Employee>();

    if(!hs.add(i2)){
      // do some operation here
    }

您还需要覆盖equals method此处。

public boolean equals(Object obj) {
        if (obj == null)
            return false;
        if (obj == this)
            return true;
        if (!(obj instanceof Employee))
            return false;

        // HERE PERFORM YOUR CHECK
        if("Employee.NAME".isequals(obj.NAME))
        {return true;}
    }

还要确保hashCode() of the key objects当对象在集合中时,您放入集合中的 永远不会改变。确保这一点的最佳方法是制作您的keys immutable.

于 2013-07-31T14:28:31.233 回答