使用 Comparator 根据多个字段的值比较对象

如何通过多个字段改进对象的比较器?如果姓氏不存在,比较器必须按姓氏或名字对用户进行排序。如果没有姓氏和名字,则按用户名排序。但是这些用户必须在列表的末尾。


public static Comparator<UserConfigurationDto> BY_LASTNAME =  (u1, u2) -> {

        // if users have only username compare them

        if((u1.getLastName().isEmpty() && u1.getFirstName().isEmpty())

                && (u2.getLastName().isEmpty() && u2.getFirstName().isEmpty())){

            return u1.getUsername().compareToIgnoreCase(u2.getUsername());

        }

        //if user doesnt have firstName and LastName drop them at the end

        if(u1.getLastName().isEmpty() && u1.getFirstName().isEmpty()){

            return 1000000 + getWeight(u1.getUsername());

        }

        if(u2.getLastName().isEmpty() && u2.getFirstName().isEmpty()){

            return -1000000 + getWeight(u2.getUsername());

        }

      String s1 = u1.getLastName().isEmpty() ? u1.getFirstName() : u1.getLastName();

      String s2 = u2.getLastName().isEmpty() ? u2.getFirstName() : u2.getLastName();

      return s1.compareToIgnoreCase(s2);

    };

}

private static int getWeight(String s){

    return s.codePoints().sum();

}

有人知道如何改进吗?我尝试使用 Comparator.comparing 和 Comparator.thenComparing 但它们产生的结果不正确


陪伴而非守候
浏览 276回答 3
3回答

UYOU

1)return 1000000 + getWeight(u1.getUsername());并且&nbsp;return -1000000 + getWeight(u2.getUsername());不是必需的。如果您参考javadoc&nbsp;return 1,则更清晰并产生相同的结果:return -1CompareTo()比较此对象与指定对象的顺序。返回&nbsp;负整数、零或正整数,因为此对象小于、等于或大于指定对象2)你没有链接字段比较,但你有 3 种方法根据比较对象的状态进行排序。因此,代码定义每个案例有点冗长的事实最终是正常的。当您重复大量user.getLastName().isEmpty()调用时,您仍然可以使用提取方法来减少它。例如 :public static Comparator<UserConfigurationDto> BY_LASTNAME =&nbsp; (u1, u2) -> {&nbsp; &nbsp; &nbsp; &nbsp; // first case&nbsp; &nbsp; &nbsp; &nbsp; if( u1.isLastAndFirstNameEmpty() && u2.isLastAndFirstNameEmpty()){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return u1.getUsername().compareToIgnoreCase(u2.getUsername());&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // second case&nbsp; &nbsp; &nbsp; &nbsp; if(u1.isLastAndFirstNameEmpty()){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 1;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else if(u2.isLastAndFirstNameEmpty()){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return -1;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // third case&nbsp; &nbsp; &nbsp; &nbsp; String s1 = u1.getLastName().isEmpty() ? u1.getFirstName() : u1.getLastName();&nbsp; &nbsp; &nbsp; &nbsp; String s2 = u2.getLastName().isEmpty() ? u2.getFirstName() : u2.getLastName();&nbsp; &nbsp; &nbsp; &nbsp; return s1.compareToIgnoreCase(s2);&nbsp; &nbsp; };

尚方宝剑之说

我认为您可以使用包含键比较器的 Java 8 静态比较函数来实现此目的。String 有一个方便的不区分大小写的比较器,您也可以在一些地方使用它。Comparator.comparing(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (UserConfigurationDto u) -> u.getLastName().isEmpty()?u.getFirstName():u.getLastName(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((s1, s2) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(s1.isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else if(s2.isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return -1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return String.CASE_INSENSITIVE_ORDER.compare(s1, s2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .thenComparing(UserConfigurationDto::getUsername, String.CASE_INSENSITIVE_ORDER);

慕工程0101907

你出错的地方是试图应用“权重”的概念。在 Java 中处理比较器时,函数中唯一重要的值是 0、大于 0 和小于 0。这样的事情似乎有效:public static final Comparator<UserConfgurationDto> BY_LASTNAME = ( u1, u2 ) ->{&nbsp; &nbsp; boolean u1hasName = !u1.getLastName().isEmpty() || !u1.getFirstName().isEmpty();&nbsp; &nbsp; boolean u2hasName = !u2.getLastName().isEmpty() || !u2.getFirstName().isEmpty();&nbsp; &nbsp; if ( u1hasName && !u2hasName )&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // u1 < u2&nbsp; &nbsp; &nbsp; &nbsp; return -1;&nbsp; &nbsp; }&nbsp; &nbsp; else if ( !u1hasName && u2hasName )&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // u2 < u1&nbsp; &nbsp; &nbsp; &nbsp; return 1;&nbsp; &nbsp; }&nbsp; &nbsp; else if ( u1hasName && u2hasName )&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; String s1 = u1.getLastName().isEmpty() ? u1.getFirstName() : u1.getLastName();&nbsp; &nbsp; &nbsp; &nbsp; String s2 = u2.getLastName().isEmpty() ? u2.getFirstName() : u2.getLastName();&nbsp; &nbsp; &nbsp; &nbsp; return s1.compareToIgnoreCase( s2 );&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return u1.getUsername().compareToIgnoreCase( u2.getUsername() );&nbsp; &nbsp; }};
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java