为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

陪伴而非守候 2022-12-28 15:44:27
如何通过多个字段改进对象的比较器?如果姓氏不存在,比较器必须按姓氏或名字对用户进行排序。如果没有姓氏和名字,则按用户名排序。但是这些用户必须在列表的末尾。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 但它们产生的结果不正确
查看完整描述

3 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

1)return 1000000 + getWeight(u1.getUsername());并且 return -1000000 + getWeight(u2.getUsername());不是必需的。如果您参考javadoc return 1,则更清晰并产生相同的结果:return -1CompareTo()

比较此对象与指定对象的顺序。返回 整数、整数,因为此对象小于、等于或大于指定对象

2)你没有链接字段比较,但你有 3 种方法根据比较对象的状态进行排序。因此,代码定义每个案例有点冗长的事实最终是正常的。
当您重复大量user.getLastName().isEmpty()调用时,您仍然可以使用提取方法来减少它。

例如 :

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


        // first case

        if( u1.isLastAndFirstNameEmpty() && u2.isLastAndFirstNameEmpty()){

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

        }

        // second case

        if(u1.isLastAndFirstNameEmpty()){

            return 1;

        }

        else if(u2.isLastAndFirstNameEmpty()){

            return -1;

        }

        // third case

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

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

        return s1.compareToIgnoreCase(s2);

    };


查看完整回答
反对 回复 2022-12-28
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

我认为您可以使用包含键比较器的 Java 8 静态比较函数来实现此目的。String 有一个方便的不区分大小写的比较器,您也可以在一些地方使用它。

Comparator.comparing(

                (UserConfigurationDto u) -> u.getLastName().isEmpty()?u.getFirstName():u.getLastName(),

                ((s1, s2) -> {

                    if(s1.isEmpty()) {

                        return 1;

                    } else if(s2.isEmpty()) {

                        return -1;

                    }

                    else {

                        return String.CASE_INSENSITIVE_ORDER.compare(s1, s2);

                    }

                }))

                .thenComparing(UserConfigurationDto::getUsername, String.CASE_INSENSITIVE_ORDER);


查看完整回答
反对 回复 2022-12-28
?
慕工程0101907

TA贡献1887条经验 获得超5个赞

你出错的地方是试图应用“权重”的概念。在 Java 中处理比较器时,函数中唯一重要的值是 0、大于 0 和小于 0。


这样的事情似乎有效:


public static final Comparator<UserConfgurationDto> BY_LASTNAME = ( u1, u2 ) ->

{

    boolean u1hasName = !u1.getLastName().isEmpty() || !u1.getFirstName().isEmpty();

    boolean u2hasName = !u2.getLastName().isEmpty() || !u2.getFirstName().isEmpty();


    if ( u1hasName && !u2hasName )

    {

        // u1 < u2

        return -1;

    }

    else if ( !u1hasName && u2hasName )

    {

        // u2 < u1

        return 1;

    }

    else if ( u1hasName && u2hasName )

    {

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

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


        return s1.compareToIgnoreCase( s2 );

    }

    else

    {

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

    }

};


查看完整回答
反对 回复 2022-12-28
  • 3 回答
  • 0 关注
  • 360 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号