【问题标题】:Efficient way to add object to set and order by object property.通过对象属性添加对象以设置和排序的有效方法。
【发布时间】:2014-04-04 16:52:57
【问题描述】:

我正在尝试构建一个选择菜单对象。我正在使用休眠标准来构建我的对象列表。我正在尝试将我的连接表对象添加到集合中以消除重复项。然后我想通过对象中的属性对集合进行排序,一旦排序,我需要将其添加到数组列表中,最后在列表末尾添加一个额外的条目。

这是我到目前为止所拥有的。

public class Computer {

    private String name;

    //other properties getter/setter
}

选择菜单查询

public List<Computer> getComputerList() {
    //Hibernate critera query
    List<ComputerConfiguration> results = session.criteraQuery(ComputerConfiguration.class).add(Restrictions.eq("processor", "amd")).list();

    Set<Computer> computerSet = HashSet();

    //Get joined object and add to set to remove duplicates
    for(ComputerConfiguration computerConfiguration : results) {
        computerSet.add(computerConfiguration.getComputer());
    }

    List<Computer> computers = new ArrayList<>(computerSet);
    //Need to somehow order by computer.getName();

    //Lastly add the following
    computers.add("Other");

    //Return computers to select model
    return computers;
}

删除重复对象然后按属性名称对它们进行排序的最有效方法是什么?我最初只是尝试对标准查询进行排序,但是该集合似乎没有保持其位置。

谢谢。

【问题讨论】:

  • 你可以改变你的查询只返回唯一的结果,你根本不需要使用 Set
  • @Jakub hr 不幸的是我不知道如何做到这一点。
  • 您应该更详细地描述您的Computer 课程。它是否具有equals(和hashCode)的适当实现?应该使用什么排序规则?
  • 我目前只用哈希等于覆盖 id "pk"。除了我的身份证,班上只有名字。非常简单的查找表。

标签: java hibernate


【解决方案1】:

使用TreeSet 对其中的元素进行排序。您可以在创建集合时提供自定义Comparator

Set<Computer> computerSet = new TreeSet<Computer>(new Comparator<Computer>() {
    @Override
    public int compare(Computer computer1, Computer computer2) {
        //write the logic to define which computer is greater than the other...
    }
});

请注意,您的 Computer 类不需要实现 equalshashCode 即可在 TreeSet 中使用。

【讨论】:

  • 您在这里应该非常小心。使用与equals 不一致的比较器可能会导致问题。 TreeSet的JavaDoc中明确提到:注意一个set维护的顺序(无论是否提供显式比较器)必须与equals一致才能正确实现Set接口
【解决方案2】:

使用HashSet 来确保计算机是唯一的(就像您目前正在做的那样)很好 - 假设您已经适当地实现了hashCodeequals

为了按名称对计算机的List进行排序,你可以写

Collections.sort(computers, new Comparator<Computer>()
{
    @Override
    public int compare(Computer c0, Computer c1)
    {
        return c0.getName().compareTo(c1.getName());
    }
});

虽然用TreeSet 解决这个问题可能很诱人(因为它可以在一次运行中排序和删除重复项),但您应该仔细考虑您的比较标准是否与equals一致为在TreeSetComparator的JavaDoc中描述:

当且仅当 c.compare(e1, e2)==0 具有与 e1.equals(e2) 相同的布尔值时,比较器 c 对一组元素 S 施加的排序被称为与 equals 一致对于 S 中的每个 e1 和 e2。

(http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html)

这里的关键问题是:是否有两台计算机具有相同的名称(由getName() 返回)但仍应被视为“相等”吗?

但是,如果排序标准与equals一致,那么使用TreeSet和适当的比较器是可行的。

【讨论】:

  • 要回答您的问题,不,两台计算机不可能有相同的名称,例如 Dell、HP、IBM 等。为什么不使用 user3173787 建议的 SortedSet?
  • @CodeJunkie SortedSet 方法与 Luiggi Mendoza 已经建议的 TreeSet 方法基本相同。再说一遍:当排序与 equals 一致时,这是一种可行(而且更容易)的方法。答案的唯一区别是 user3173787 建议让 Computer 实现 Comparable,我会建议:计算机之间没有“自然排序”。另见stackoverflow.com/a/21659849
  • 我最终按照 Luiggi Mendoza 的建议使用了 Treeset,但决定将您标记为最佳答案,因为它解释得很好,很可能会帮助其他人。 .
【解决方案3】:

您可以尝试在填充集合时使用 SortedSet 对计算机进行实际排序: SortedSet

另外,我不太明白你的台词

computers.add("Other")

computers 是一个 Computer 对象 ArrayList 你它可能不起作用。所以这是我的完整解决方案:

首先,使计算机对象具有可比性:

public class Computer implements Comparable<Computer> {

    private String name;

    public Computer (String name) { this.name = name; }

    public int compareTo(Computer c) {          
       return name.compareTo(c.name) ;          
   }
}

您现在可以像这样使用 SortedSet:

public List<Computer> getComputerList() {
    List<ComputerConfiguration> results = session.criteraQuery(ComputerConfiguration.class).add(Restrictions.eq("processor", "amd")).list();

    SortedSet<Computer> computerSet = new TreeSet<>();
    for(ComputerConfiguration computerConfiguration : results) {
        computerSet.add(computerConfiguration.getComputer());
    }
    computerSet.add(new Computer("Other");

    List<Computer> computers = new ArrayList<>(computerSet);
    return computers;
}

【讨论】:

  • Opps,从记忆中写下我的问题时出现了一个简单的错误,它应该是一台新的计算机(“其他”);它的目的是在我的选择菜单中添加一个“其他”选项。我将阅读有关 SortedSet 的内容。我想知道如果 SortedSet 会保持插入顺序,我是否在休眠查询中对结果进行排序。如果是这样,就不需要比较器了。
  • 如果您的结果已经排序,则不需要 SortedSet 和比较器。您可以简单地使用一个简单的 Set,遍历结果并添加它们。
  • 有趣,我的印象是集合不会持有插入订单。好的,我会在 poj 中尝试一下。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2016-07-15
相关资源
最近更新 更多