【问题标题】:Comparator is not working, I can't find the mistake比较器不工作,我找不到错误
【发布时间】:2018-11-08 20:53:29
【问题描述】:

我正在尝试使用比较器对象对从数据库中获取的对象列表进行排序。它应该比较 last names 并且如果 last names 相同,它应该比较 first names 并确定它们的顺序,所以如果我有类似的列表那:

[Jon Doe][Zed Adams][John Adams]

应该是这样排序的:

[John Adams][Zed Adams][Jon Doe]

现在让我们看看我的代码:

比较器类:

public class ComparatorContactByName implements Comparator<Contact> {
    @Override
    public int compare(Contact c1, Contact c2) {

        // if lastNames of compared objects are not the same, compare them
        if(!c1.getLastName().toLowerCase().equals(c1.getLastName().toLowerCase())){
            return c1.getLastName().compareTo(c2.getLastName());

        // if lastNames are the same, compare by firstName
        }else if(c1.getLastName().toLowerCase().equals(c1.getLastName().toLowerCase())){
            return c1.getFirstName().toLowerCase().compareTo(c2.getFirstName().toLowerCase());

            // other case like firstName and lastName are the same, compare by id
        }else{
            return c1.getContactId() - c2.getContactId();
        }
    }
}

控制器方法:

public void getAllContactsSortedByName(){

    List<Contact> allContacts = ContactRepository.listAllContacts();

    Comparator comparatorContactByName = new ComparatorContactByName();

    Collections.sort(allContacts, comparatorContactByName);

    if (allContacts == null) {
        System.out.println("No contact found. ");
    } else {
        for (Contact contact : allContacts) {
            System.out.println(contact.toString());
        }
    }
}

调用此方法后,我得到如下输出:

Contact{contactId= 133, firstName= John, lastName= Adams, email= ja@email.com, groups= [gym]}    
Contact{contactId= 126, firstName= Jon, lastName= Doe, email= jd@email.com, groups= [work, gym]}    
Contact{contactId= 130, firstName= Zed, lastName= Adams, email= za@email.com, groups= [work]}

“Zed”应该是第二名,但他是最后一名。任何想法如何解决这个逻辑?

【问题讨论】:

  • 在 Java 8+ 中:Comparator.comparing(Contact::getLastName).thenComparing(Concat::getFirstName).thenComparingInt(Contact::getConcatId).
  • 在“c1.getLastName().toLowerCase().equals(c1.getLastName().toLowerCase())”中:您使用了两次c1。无论如何都要使用c1.getLastName().equalsIgnoreCase(c2.getLastName())
  • 在 compare() 中,你的 if 语句比较 c1 和 c1,而不是比较 c1 和 c2。
  • 还要注意else if 的条件是if 条件的补集,所以你永远不会到达最后的else

标签: java sorting collections java-8 comparator


【解决方案1】:

这就是你所做的:

c1.getLastName().toLowerCase().equals(c1.getLastName().toLowerCase()

您正在比较 c1's 的姓氏和 c1's 的姓氏

改为这样做:

c1.getLastName().toLowerCase().equals(c2.getLastName().toLowerCase()

名字也一样!

【讨论】:

    【解决方案2】:

    使用Comparator API:

     Comparator<Contact> comparator = 
           Comparator.comparing(Contact::getLastName, String.CASE_INSENSITIVE_ORDER)
                     .thenComparing(Concat::getFirstName, String.CASE_INSENSITIVE_ORDER)
                     .thenComparingInt(Contact::getContactId);
    

    【讨论】:

    • 这是不区分大小写的比较吗?
    • @Lothar 它正在使用String.comapreTo 方法。区分大小写。
    • @Lothar 对于不区分大小写的比较,请使用comparing(Contact::getLastName, String.CASE_INSENSITIVE_ORDER)。对于语言敏感的比较,使用例如comparing(Contact::getLastName, Collator.getInstance(Locale.US)).
    • @ETO 问题包含不区分大小写的比较。
    猜你喜欢
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多