【问题标题】:Java: Sort a list of Objects using Comparator with second word of the propertyJava:使用带有属性的第二个单词的比较器对对象列表进行排序
【发布时间】:2018-02-23 10:16:57
【问题描述】:

我有一个objects 列表,我想根据name 对其进行排序。我已经完成了编码,它确实根据name 进行了排序,但我的要求略有不同。

名称是我目前使用以下代码排序的示例:

Bull AMP
Cat DEF
Dog AMP
Frog STR
Zebra DEF

但我希望根据名称中的第二个单词对名称进行排序。基本上list 应该是这样的:

Bull AMP
Dog AMP
Cat DEF
Zebra DEF
Frog STR

下面是我的代码:

对象类:

public class AnimalData implements Serializable
{
    private static final long serialVersionUID = 3952396152688462601L;
    public String name;
    public long age;
    private String animal;
    private String animalParts;
    private String animalType;
}

比较器类

public class AnimalDataComparer implements Comparator<AnimalData> 
      {
  @Override
  public int compare(final AnimalData object1, final AnimalData object2) 
  {
          return object1.getName().compareTo(object2.getName());
  }
  }

使用集合排序

  private List<AnimalData> AnimalDataList;

  Collections.sort(AnimalDataList, AnimalDataComparer);

【问题讨论】:

  • 您的 equals 方法也需要表示该行为。
  • 什么是 AMP、DEF 等字段??
  • 或者这些后缀是字段字符串名称的一部分吗?
  • 您可以使用split() 并比较名称的第二部分。
  • 这真是糟糕的设计。如果可能,您应该为namecategory 添加单独的字段。如果您需要这样的格式,请添加类似String foo() { return name + " " + category; } 的方法

标签: java list sorting arraylist comparator


【解决方案1】:

像这样更改您的比较器:

public class AnimalDataComparer implements Comparator<AnimalData> 
{
    @Override
    public int compare(final AnimalData object1, final AnimalData object2) 
    {
      return object1.getName().split(" ")[1].compareTo(object2.getName().split(" ")[1]);
    }
}

或使用 Java 较新的 Comparator API:

Comparator<AnimalData> c = Comparator.comparing(animal -> animal.getName().split(" ")[1]);

请注意,这是假设所有名称实际上都有两个单词。如果您不确定,则需要在访问拆分数组之前进行检查。

除此之外,您可能还想考虑其他 cmets 并在构造函数中拆分名称并拥有两个字段,namecategory。或者您可以为类别编写一个 getter,在其中进行拆分和验证。

【讨论】:

    【解决方案2】:

    这个需要自己实现,如下,假设单词是name的一部分,有substring()indexOf()

    @Override
    public int compare(final AnimalData object1, final AnimalData object2) 
    {
        return object1.getName().substring(
            object1.getName().indexOf(" ") 
        ).compareTo(object2.getName().substring(
            object2.getName().indexOf(" ")
        ));
    }
    

    如果由于某种原因你有两个以上的词,而最后一个是你想要的,那么使用lastIndexOf()

    【讨论】:

      【解决方案3】:

      在 Java 8 流模式下:

      Comparator<? super Animal> animalComparator = (a, b) -> {
              StringTokenizer firstTokenizer = new StringTokenizer(a.getName(), " ");
              firstTokenizer.nextToken();
              StringTokenizer secondTokenizer = new StringTokenizer(b.getName(), " ");
              secondTokenizer.nextToken();
              return firstTokenizer.nextToken().compareTo(secondTokenizer.nextToken());
          };
      
          myList = myList.stream().sorted(animalComparator).collect(Collectors.toList());
      

      【讨论】:

      • 这不是“完整”的 Java 8 代码——它复制了两个参数的比较器逻辑。
      • 嗯,有两个不同的变量需要比较,因为它使用的是 StringTokenizer 类
      【解决方案4】:

      在这里

      输出::

      [AnimalData [name=Dog AMP]、AnimalData [name=Cat DEF]、AnimalData [name=Zebra DEF]、AnimalData [name=Frog STR]]

      import java.io.IOException;
      import java.io.Serializable;
      import java.text.ParseException;
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.List;
      
      public class test {
          public static void main(String[] args) throws IOException, ParseException {
      
              AnimalData data1 = new AnimalData("Cat DEF");
              AnimalData data2 = new AnimalData("Dog AMP");
              AnimalData data3 = new AnimalData("Frog STR");
              AnimalData data4 = new AnimalData("Zebra DEF");
              List<AnimalData> list = new ArrayList<>();
              list.add(data1);
              list.add(data2);
              list.add(data3);
              list.add(data4);
              Collections.sort(list);
              System.out.println(list);
      
          }
      }
      
      class AnimalData implements Serializable, Comparable<AnimalData> {
          private static final long serialVersionUID = 3952396152688462601L;
          public String name;
          public long age;
          private String animal;
          private String animalParts;
          private String animalType;
      
          public AnimalData(String name) {
              super();
              this.name = name;
          }
      
          @Override
          public int compareTo(AnimalData o) {
              String secondPartThis = this.name.split(" ")[1];
              String secondPartObject = o.name.split(" ")[1];
              return secondPartThis.compareTo(secondPartObject);
          }
      
          @Override
          public String toString() {
              return "AnimalData [name=" + name + "]";
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-02
        • 2012-01-15
        • 2018-09-28
        • 2018-09-10
        • 2014-04-12
        • 1970-01-01
        相关资源
        最近更新 更多