首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何排序字符串中包含alpha数字字符(如ROLL-10 > ROLL-2 )的字符串

如何排序字符串中包含alpha数字字符(如ROLL-10 > ROLL-2 )的字符串
EN

Stack Overflow用户
提问于 2022-09-21 15:03:36
回答 2查看 45关注 0票数 -1

我想对我的自定义对象进行排序,其中它有两个字段。1)平码(长)和2)滚动(字母数字)。我想按自然顺序对平码进行排序,但当它们相同时,我想按滚动号降序排序。

我使用的是Java 8比较器,我有以下代码。

型号:

代码语言:javascript
复制
public class AreaModel {

   public long pinCode;
   public String rollNo;

   public AreaModel(long pinCode, String rollNo) {
      super();
      this.pinCode = pinCode;
      this.rollNo = rollNo;
   }
   public long getPinCode() {
     return pinCode;
   }
   public void setPinCode(long pinCode) {
      this.pinCode = pinCode;
   }
   public String getRollNo() {
     return rollNo;
   }
   public void setRollNo(String rollNo) {
      this.rollNo = rollNo;
   }

   @Override
   public String toString() {
      return "["+pinCode+" "+rollNo+"]";
   }
}

Main:

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.javainuse.model.AreaModel;

public class MainClass {
 public static void main(String[] args) {
    List<AreaModel> list = new ArrayList<AreaModel>();
    list.add(new AreaModel(535005, "2"));
    list.add(new AreaModel(535006, "100"));
    list.add(new AreaModel(535007, "30"));
    list.add(new AreaModel(535005, "ROLE-45"));
    list.add(new AreaModel(535005, "ROLE-10"));
    list.add(new AreaModel(535005,"13"));
    list.add(new AreaModel(535005,"70"));
    
    Function<AreaModel, Long> retentionCodeSequence = AreaModel::getPinCode;
    Function<AreaModel, String> retentionDuration = AreaModel::getRollNo;

    // sort area by pincode, then by role 
    Comparator<AreaModel> lastThenFirst = Comparator.comparing(retentionCodeSequence).thenComparing(retentionDuration,Comparator.reverseOrder());

    list= list.stream().sorted(lastThenFirst).collect(Collectors.toList());
    
    System.out.println("***");
    System.out.println(list);
    
}
}

有了这个,我得到的输出就是

[535005角色-45,535005角色-10,535005 70,535005 2,535005 13,535006 100,535007 30]

我所期待的是

[535005 70,535005角色-45,535005 13,535005角色-10,535005 2,535006 100,535007 30]

正如您所看到的,即使已经排序,角色也没有。角色可以包含整个数字作为字符串,或者是以文本为后缀的数字。我该怎么解决呢?

编辑:使用字符串中可能的值更新的问题

EN

回答 2

Stack Overflow用户

发布于 2022-09-21 15:31:08

假设属性rollNo的所有有效值都具有格式"PREFIX-DIGITS",即它从一个可选前缀开始,包含一个非数字字符,后面跟着一个破折号,并以一个强制数字部分结尾,那么您可以构造一个下面的比较器,它分别处理数字部分和非数字部分。

代码语言:javascript
复制
Comparator<AreaModel> lastThenFirst =
    Comparator.comparing(AreaModel::getPinCode)
        .thenComparing(Comparator
            .<AreaModel, String>comparing(area -> area.getRollNo().replaceAll("\\d", ""), Comparator.reverseOrder())
            .thenComparing(area -> Integer.parseInt(area.getRollNo().replaceAll("\\D","")), Comparator.reverseOrder())
        );

注意到,当有几个AreaModel实例具有相同的pinCode,其中一个实例的rollNo值中没有非数字部分时,则该实例将是排序后的最后一个实例(在具有相同密码的组中)。如果需要相反的行为,则可以通过在链中再添加一个比较器来单独检查这种情况:

代码语言:javascript
复制
Comparator<AreaModel> lastThenFirst =
    Comparator.comparing(AreaModel::getPinCode)
        .thenComparing(
            Comparator.<AreaModel, Boolean>comparing(area -> area.getRollNo().matches("\\d"))
                .thenComparing(area -> area.getRollNo().replaceAll("\\d", ""), Comparator.reverseOrder())
                .thenComparing(area -> Integer.parseInt(area.getRollNo().replaceAll("\\D", "")), Comparator.reverseOrder())
        );
票数 0
EN

Stack Overflow用户

发布于 2022-09-22 11:32:49

正如@g00se所提到的,角色中的整数值应该被解析并在比较器中使用。

此外,ToLongFunction可用于处理pinCode,默认的List::sort应用于对当前列表进行排序。

代码语言:javascript
复制
ToLongFunction<AreaModel> pinCode = AreaModel::getPinCode;
ToIntFunction<AreaModel> roleToInt = am -> Integer.parseInt(am.getRollNo().replaceAll("\\D", ""));
Comparator<AreaModel> byRoleDesc = Comparator.comparingInt(roleToInt).reversed();

// sort area by pincode, then by role
Comparator<AreaModel> byPinAndReversedRole = Comparator
        .comparingLong(pinCode)
        .thenComparing(byRoleDesc);

list.sort(byPinAndReversedRole);
// -> [[535005 70], [535005 ROLE-45], [535005 13], [535005 ROLE-10], [535005 2], [535006 100], [535007 30]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73803054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档