【问题标题】:Return a sorted List<Object> where first item value is always empty返回一个排序的 List<Object> ,其中第一项值始终为空
【发布时间】:2017-05-10 13:11:09
【问题描述】:

使用Object 列表,其中一项为空String。尝试编写将返回排序列表的方法。通过排序方式,列表的第一项值应始终为空String

由于我不想操作未排序的列表,因此我正在创建一个新列表进行排序。

到目前为止,我的代码是:

   private List<LoggerConfig> sort(List<LoggerConfig> unSortedList) {

    List<LoggerConfig> sortedList = new ArrayList<LoggerConfig>(unSortedList);

    //What to do here

    return sortedList;
}

看了很多SO 的帖子,但很困惑。

【问题讨论】:

  • 如果我正确理解了这个问题:您想对列表进行排序,但一个元素的 String 值为空,排序后您希望该元素成为第一个元素?
  • 已排序列表的第一个元素的String 值应为空,该值存在于未排序列表中。所以不确定是否需要排序或者只是检查 unsortedlist 的元素并在条件匹配时将元素放入 sortedlist 的零索引。

标签: java linked-list


【解决方案1】:

您可以信任 String.compareTo 来匹配您寻求的订单。这是一个比较器:

new Comparator<LoggerConfig>() {
  @Override
  public int compare(LoggerConfig o1, LoggerConfig o2) {
    return (o1.getName().compareTo(o2.getName()));
  }
};

或者直接在具体类中实现Comparable(这里是Dummy)

class Dummy implements Comparable<Dummy>{

    String name;

    public int compareTo(Dummy o) {
        return this.name.compareTo(o.name);
    }
}

为什么:

String.compareTo检查两者的第一个字符以找出差异(直到两者的最小长度),如果它们匹配,则使用长度来产生差异,最长的将在最短的之后(shortest.compareTo(longuest)将返回一个负值(长度差)。

在这种情况下,"".compareTo("abc"),空字符串中没有字符,因此跳过第一次检查并使用长度来比较Strings,因此空的String将始终被视为首先比较任何“非空”String

以前面Dummy类为例(只需添加构造函数Dummy(String)

public class Main {

    public static void main(String[] args) {
       List<Dummy> dummies = new LinkedList<Dummy>();
       dummies.add(new Dummy("abc.com.core"));
       dummies.add(new Dummy(""));
       dummies.add(new Dummy("abc.com.core.def"));

       System.out.println("BEFORE : " + dummies);
       Collections.sort(dummies);
       System.out.println("AFTER : " + dummies);
    }
}

输出:

BEFORE : [abc.com.core, , abc.com.core.def]
AFTER : [, abc.com.core, abc.com.core.def]

【讨论】:

  • 你是对的,String 自己的compareTo 已经考虑并清空String 比任何其他值都少。
  • 但不确定它是否有效,因为我的测试失败了。 @Test public void testSort() { List unsortedList = makeUnsortedList(); EasyMock.replay(item1,item2,item3); List sortedList =tested.sort(unsortedList); assertTrue(sortedList.get(0).getName().isEmpty()); assertTrue(sortedList.get(1).equals("com.abc.core") || sortedList.get(1).equals("com.abc.core.AA")); assertTrue(sortedList.get(2).equals("com.fwk.core") || sortedList.get(2).equals("com.abc.core.AA")); }
  • 你能用正确缩进的测试来编辑你的问题吗?) cmets 不适合显示代码。我一回家就测试一下(1小时)
  • @shaz 但您没有在示例中使用自定义 Comparator 调用 Collections.sort
  • @AxelH:在测试中调用tested.sort(unsortedList);
【解决方案2】:

您可以将此条件放在比较器中,以便将具有空值的元素视为“小于”其他元素,以便它显示在排序列表的开头。试试这样的:

Collections.sort(sortedList, new Comparator<LoggerConfig>() {
  @Override
  public int compare(LoggerConfig o1, LoggerConfig o2) {
    if(o1.getName().isEmpty(){
      return -1;
    }
    if(o2.getName().isEmpty(){
      return 1;
    }
    return (o1.getName().compareTo(o2.getName()));
  }
});

我没有对此进行测试,但这应该可以使这个想法变得清晰。如果空元素出现在列表末尾,请交换 -11

如果您的 List 很大并且排序需要很多时间,最好在排序之前删除空元素,然后排序,然后将元素放在开头。

【讨论】:

  • 这基本上是String.compareTo(String) 将返回的内容
  • @AxelH 如果StringcompareTo 以同样的方式处理空字符串,OP 的比较器就足够了。这个问题听起来好像没有按预期工作。
  • 嗯,他问“我需要在这里进行如下比较吗?”所以我怀疑代码没有尝试过。我很快用String 运行了一个sn-p 来确定,因为我不确定,如果你想看我的答案。我将添加代码
【解决方案3】:

Comparator 解决方案对我来说似乎可行;您缺少的是实现 compare 方法,以便它执行您想要的操作。

Collections.sort(sortedList, new Comparator<LoggerConfig>() {
    @Override
    public int compare(LoggerConfig o1, LoggerConfig o2) {
        if(o1.getName().equals("")){
            return -1;
        } else if(o2.getName().equals("")) {
            return 1;
        } else {
            return (o1.getName().compareTo(o2.getName()));
        }
    }
});

根据Java docsComparator 有一个 compare 方法,它返回一个 int

  • 如果第一个参数小于第二个,则小于 0
  • 如果参数相等则为 0
  • 如果第一个参数大于第二个,则大于 0

所以你需要的Comparator应该返回两个字符串的比较,如果它们都不同于"",如果第一个(或第二个)字符串为空,则返回-1(或1)。

【讨论】:

  • 我们有同样的想法。不可能不赞成这个:)
  • 我也在想同样的事情 :)
  • 这基本上是String.compareTo(String) 将返回的内容
  • 这是比较同一列表中的两个项目。不明白。它将如何返回第一个元素的值为空的新列表(排序)?还需要迭代器吗?
  • @shaz Collections.sort 使用Comparator 实例来检查列表中的每个条目。当Collections.sort 完成时,您作为参数提供给它的List 将被排序。如果您需要 List 的新实例,请在排序前创建它的副本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
  • 2020-09-13
  • 1970-01-01
相关资源
最近更新 更多