简体   繁体   English

使用Java流排序时将数字解析为字符串的简单方法吗?

[英]Simple way to parse numbers as strings while sorting with Java streams?

I have a list of objects that contain values stored as strings but are actually numbers and I'm trying to find a way to parse strings to integers within a Java stream to sort them numerically. 我有一个对象列表,其中包含以字符串形式存储的值,但实际上是数字,我试图找到一种方法来将字符串解析为Java流中的整数以对其进行数字排序。 Here's what I got so far. 这是到目前为止我得到的。

List<SearchResultObject> returnedValues = doTheSearchMethod();
returnedValues = returnedValues
.stream()
.sorted(Comparator.comparing(SearchResultObject::getNumber))
.collect(Collectors.toList());

As of right now this kind of works, but the problem is that because those numbers are actually strings, it sorts the numbers lexicographically, not numerically. 到目前为止,这种工作方式仍然存在,但问题在于,由于这些数字实际上是字符串,因此按字典顺序而不是数字对数字进行排序。 Is there a way to incorporate parsing into the stream? 有没有办法将解析合并到流中? All numbers are padded to be the same size. 所有数字均填充为相同大小。

3356001017053000000000000
3356001017002000000000000
3356001017004000000000000
3356001017026000000000000
5101004003020000000000000
4123000006002510000000000
4758000005010000000000000

use comparingLong and then parse long. 使用comparingLong然后解析很长的时间。 the numbers are too large for integers. 数字对于整数太大。

returnedValues.sort(Comparator.comparingLong(sro->Long.parseLong(sro.getNumber())));

For just sorting you don't need stream, just use custom Comparator using lambda expression 对于仅排序,您不需要流,只需使用使用lambda表达式的自定义Comparator

Comparator<SearchResultObject> c = Comparator.comparingLong(s->Long.parseLong(s.getNumber()));

And then use Collections.sort method 然后使用Collections.sort方法

Collections.sort(returnedValues,c);

You don't need to use Streams API for sorting the list, you can directly use sort() method from the List interface. 您不需要使用Streams API对列表进行排序,可以直接从List接口使用sort()方法。 You just need to ensure that you provide a proper comparator to the sort() method. 您只需要确保为sort()方法提供适当的comparator即可。

As you mentioned, you can directly use: 如前所述,您可以直接使用:

Comparator.comparing(SearchResultObject::getNumber)

comparator to compare the strings. 比较器比较字符串。

However, as you need the list to be sorted by comparing the Integer/Long, you can use the following: 但是,由于您需要通过比较整数/长整数来对列表进行排序,因此可以使用以下命令:

  1. For Integer: 对于整数:

    list.sort(Comparator.comparingInt(s ->Integer.parseInt(s.getNumber())));

  2. For Long: 长期:

    list.sort(Comparator.comparingLong(s ->Long.parseLong(s.getNumber())));

You can check the output for the following code below: 您可以在下面的代码中检查输出:

Before sorting
SearchResultObject{number='100'}
SearchResultObject{number='2'}
SearchResultObject{number='10'}
After sorting
SearchResultObject{number='2'}
SearchResultObject{number='10'}
SearchResultObject{number='100'}

The above output is based on the assumption the SearchResultObject contains a number as the field. 上面的输出基于SearchResultObject包含number作为字段的假设。

If you can modify SearchResultObject add a method to it converting the String to BigInteger and use it in your Comparator 如果可以修改SearchResultObject向其添加一个将String转换为BigInteger的方法,并在Comparator使用它

public SearchResultObject {
    ...
    public BigInteger getNumberAsBigInteger() {
        return new BigInteger(this.number);
    }
    ...
}

And the invocation is 调用是

returnedValues.stream()
              .sorted(
                  Comparator.comparing(
                      SearchResultObject::getNumberAsBigInteger
                  )
              )
              .collect(Collectors.toList());

If you can't modify the SearchResultObject class, then you'll have to customize your Comparator a bit, but nothing too complicated 如果您不能修改SearchResultObject类,则必须对自定义Comparator进行一些自定义,但是没有什么太复杂的了

returnedValues.stream()
              .sorted(
                  Comparator.comparing(
                      sro -> new BigInteger(sro.getNumber())
                  )
              )
              .collect(toList());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM