【问题标题】:Sort ArrayList of objects by field in custom order按自定义顺序按字段对对象的 ArrayList 进行排序
【发布时间】:2016-12-15 22:01:31
【问题描述】:

如何实现对字段名内容的自定义排序:

  • 第一个元素:P 后跟数字 [1-9]{2} 始终在第一个
  • 后跟:P 后跟数字 0[0-9]
  • 后跟:S
  • 后跟数字 [1-9]{2}
  • 然后其余的按正常顺序i1.getName().compareToIgnoreCase(i2.getName())

    private static Comparator<Item> itemComperator = new Comparator<Item>() {
        @Override
        public int compare(Item i1, Item i2) {
            if (i1.getName().matches("P[1-9]{2}") && i2.getName().matches("P0[0-9]"))
                return -1;
            else if (i1.getName().matches("S[1-9]{2}"))
                return -1;
            else
                return i1.getName().compareToIgnoreCase(i2.getName());
        }
    };
    
    @Test
    public void sortItem() {
        Item item01 = new Item(1, "R59");
        Item item02 = new Item(2, "S48");
        Item item03 = new Item(3, "P01");
        Item item04 = new Item(4, "P25");
        Item item05 = new Item(5, "R99");
    
        List<Item> items = Arrays.asList(item01, item02, item03, item04, item05);
        System.out.println("before sorting");
        long seed = System.nanoTime();
        Collections.shuffle(items, new Random(seed));
        for (Item i : items) {
            System.out.println(i.getId() + " " + i.getName());
        }
    
        System.out.println("after sorting");
        Collections.sort(items, itemComperator);
        for (Item i : items) {
            System.out.println(i.getId() + " " + i.getName());
        }
    
    
    }
    
    public class Item {
        private int id;
        private String name;
    
        public Item(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

预期输出:

after sorting
4 P25
3 P01
2 S48
1 R59
5 R99

【问题讨论】:

  • 您能否在问题中包含所需的输出.. ???

标签: java sorting comparator


【解决方案1】:

我认为我会首先将每个输入映射到一个“种类”数字,该数字基于上面的标准列表。例如:

int kind(String input) {
  if (input.matches("P[1-9]{2}") {
    return 0;
  } else if (input.matches("P0[0-9]")) {
    return 1;
  } else if (input.matches("S.*")) {
    return 2;
  } else if (input.matches("[1-9]{2}")) {
    return 3;
  } else {
    return 4;
  }
}

这为您提供了一种查看两个字符串是否属于相同“种类”的方法;如果没有,请根据种类退回订单。如果它们是同一种,只需使用(不区分大小写)字典顺序比较它们(您没有指定,但我假设您希望例如“P11”在“P22”之前):

public int compare(Item a, Item b) {
  String nameA = a.getName();
  String nameB = b.getName();

  int kindA = kind(nameA);
  int kindB = kind(nameB);
  if (kindA != kindB) {
    return Integer.compare(kindA, kindB);
  } else {
    return nameA.compareToIgnoreCase(nameB);
  }
}

【讨论】:

  • 也许是input.matches("S.*") 而不是input.matches("S*")
猜你喜欢
  • 2013-10-28
  • 2012-02-12
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 2011-02-16
相关资源
最近更新 更多