【问题标题】:How to do sorting when I have null value in a list当我在列表中有空值时如何进行排序
【发布时间】:2021-04-13 23:41:59
【问题描述】:

我是 Java 新手,但我正在尝试将 C# 转换为 Java,在这里我遇到了一些关于排序的问题。

由于我在上面执行了 5 次循环来生成结果,所以当我的代码第一次进入这里时,result 将类似于 [5,2,3], [null], [null], [null], [null]

所以我想将它排序为result = [2,3,5], [null], [null], [null], [null]。但是当我尝试这样做时,我会点击NullPointerException。我猜这是因为我的列表包含空值。

Java 代码:

Arrays.sort(result); 
String resultSorting = Arrays.toString(result);
result[j] = String.join(",", resultSorting);

如果 C# 我可以在 lambda 中做:

var resultSorting = result[j].Split(',').OrderBy(x => x).ToList();
result[j] = string.Join(",", resultSorting);

那么如何在 Java 中解决这个问题?

【问题讨论】:

  • 您可以使用 Arrays.sort() 和 Comparator 作为第二个参数。编写一个接受空值的比较器,一切都应该没问题。
  • @Ralf Renz,感谢您的评论。我已经尝试过这个解决方案,但排序不起作用,它只接受空值。因为我的列表是[5,2,3], [null], [null] 而不是[2, null, null, 3, 5]。所以这是我不知道该怎么办的问题......
  • 好的。但是您不想对数组结果进行排序,而是对结果的元素进行排序。对数组进行循环,并根据每个元素的内容决定是否对其进行排序。

标签: java c# list spring-boot sorting


【解决方案1】:

如果是java对象的集合,可以实现Comparable接口,用于计算对象的.sort()

幸运的是,Stream API 已经有了一些有用的内置方法以及 Comparator。

例如,对于您的字符串,我已经写了这个:


@Test
@DisplayName("Sort Array of Strings with Nulls First or Last")
void sorty(){

    final String[] unsortedArray = {"Bob",null,"Alice",null,"Charlie","Emma",null,null,"Dave"};

    //To List with Stream, Sort using Comparator but with nulls first then collect to String list.
    final List<String> sortedArray = Arrays.stream(unsortedArray)
                .sorted(Comparator.nullsFirst(String::compareToIgnoreCase))
                .collect(Collectors.toList());

    //Assertions
    String[] expectedResult = {null,null,null,null,"Alice","Bob","Charlie","Dave","Emma"};
    Assertions.assertEquals(Arrays.asList(expectedResult),sortedArray);
    Assertions.assertNotEquals(Arrays.asList(unsortedArray),sortedArray);

    //Or using nullsLast:

    //To List with Stream, Sort using Comparator but with nulls last then collect to String list.
    final List<String> sortedArrayNullsLast = Arrays.stream(unsortedArray)
                .sorted(Comparator.nullsLast(String::compareToIgnoreCase))
                .collect(Collectors.toList());

    //Assertions
    String[] expectedResultNullsLast = {"Alice","Bob","Charlie","Dave","Emma",null,null,null,null};
        Assertions.assertEquals(Arrays.asList(expectedResultNullsLast),sortedArrayNullsLast);
        Assertions.assertNotEquals(Arrays.asList(unsortedArray),sortedArrayNullsLast);
        
        
    //PS: You can instead of Collect to List of Strings in the Stream to an array instead...

    //To List with Stream, Sort using Comparator but with nulls last then collect to String list. I just did
    // to list to compare them in the assertion tests.
    final String[] sortedArrayNullsLastAsArray = Arrays.stream(unsortedArray)
                .sorted(Comparator.nullsLast(String::compareToIgnoreCase))
                .toArray(String[]::new);
    }

【讨论】:

  • 这对我的情况有用吗?因为我的数组格式就像[3,2,5], [null], [null] 而不是[2, null , 3, null, null, 5]
  • 意味着实际上我想对结果的元素进行排序,而不是数组。因为我一直在尝试一些 Comparator 内置方法,它只会忽略空值,但不能对元素进行排序。
  • 对结果的元素进行排序?如果是[1,9,4], [null], [3,2,5], [null], [null],你会期待什么结果?
  • [1,4,9], [null], [2,3,5], [null], [null]。这是我期望的结果。
【解决方案2】:

我找到了解决问题的方法。

在对结果的元素进行排序之前,我会为我的结果元素拆分逗号,以便它只会对元素而不是整个数组进行排序。

//Example of my result
result = [2,5,3], [null], [null], [null], [null];

String tempResult = result[j].replaceAll(",", ""); //After split the comma, result will become [253] instead of [2,5,3], [null], [null], [null], [null];
String[] resultSplitComma = tempResult.split("");
Arrays.sort(resultSplitComma);
String resultSorting = Arrays.toString(resultSplitComma);
result[j] = String.join(",", resultSorting);

在这里,我非常感谢所有试图帮助我的人。

PS:这是我目前能想到的唯一解决方案。所以如果有人还有更好的解决方案,请随时发表评论让我了解更多:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-19
    • 2013-07-16
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    相关资源
    最近更新 更多