如何在Java中对包含数字的字符串进行排序

如何在Java中对包含数字的字符串进行排序,java,string,sorting,Java,String,Sorting,我想对一个有nr的字符串进行排序。我该怎么做 假设我的整数是 Class2 "3" "4" "1" 我主要做class2.Sort() 提前感谢。如果数字都是单位数,请将字符串拆分为字符数组并对数组进行排序。否则,必须有一个分隔符来分隔数字。使用该分隔符调用string.split并对结果数组进行排序。要排序的函数是Arrays.sort(),如果内存正常的话 javadoc参考 公共静态void main(字符串[]args) { String String=“3 42\n 11\t 7

我想对一个有nr的字符串进行排序。我该怎么做

假设我的整数是

Class2
"3"
"4"
"1"
我主要做class2.Sort()


提前感谢。

如果数字都是单位数,请将字符串拆分为字符数组并对数组进行排序。否则,必须有一个分隔符来分隔数字。使用该分隔符调用string.split并对结果数组进行排序。要排序的函数是Arrays.sort(),如果内存正常的话

javadoc参考

公共静态void main(字符串[]args)
{
String String=“3 42\n 11\t 7 dsfss 365\r 1”;
String[]number=String.split(\\D+);
排序(数字,新的比较器()
{
公共整数比较(字符串s1、字符串s2)
{
返回Integer.valueOf(s1).compareTo(Integer.valueOf(s2));
}
});
System.out.println(Arrays.toString(numbers));
}

您的问题格式不太正确,但以下是一些您应该知道的事情:

  • 有一个可用于对任意对象进行排序的方法
  • 字符串的自然顺序为
  • Java数组是协变的:字符串[]是对象[]
因此,给定
String[]sarr
,如果您想按字典顺序对其排序(即
“1”<“10”<“2”
),只需
Arrays.sort(sarr)工作。字符串是否包含数字并不重要

如果要将字符串排序为数字(即
“1”<“2”<“10”
),则需要将字符串转换为数值。根据这些数字的范围,
Integer.parseInt
可以;您可以始终使用
biginger
否则

假设需要
biginger

您现在有两个选项:

  • String[]
    转换为
    biginger[]
    ,然后由于
    biginger实现了Comparable
    ,因此可以使用
    数组。使用其自然顺序进行排序。然后可以将排序后的
    biginger[]
    转换回
    String[]

  • 字符串
    转换为
    大整数
    “即时”以供自定义
    比较器进行比较
    。由于
    Arrays.sort
    使用基于比较的mergesort,因此可以预期
    O(N log N)
    比较,因此转换次数也会尽可能多


通用解决方案是使用所谓的“自然顺序比较器”

下面是一个例子:

在字符串可能包含一系列数字的情况下,自然排序实际上是非常重要的,您希望按字母顺序排序,但按数字顺序排序。例如,现代版本的Windows资源管理器使用它来排序文件名。它还可以根据版本字符串(即“1.2.3”与“1.20.1”)选择库的最新版本

如果字符串实际上只包含数字(如您在描述中所述),那么最好不要使用字符串,而是创建整数对象

注意:上面的链接似乎已断开。代码非常有用,我将在这里发布:

/*
 * <copyright>
 *
 *  Copyright 1997-2007 BBNT Solutions, LLC
 *  under sponsorship of the Defense Advanced Research Projects
 *  Agency (DARPA).
 *
 *  You can redistribute this software and/or modify it under the
 *  terms of the Cougaar Open Source License as published on the
 *  Cougaar Open Source Website (www.cougaar.org).
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * </copyright>
 */
/*
NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
Copyright (C) 2003 by Pierre-Luc Paour <natorder@paour.com>

Based on the C version by Martin Pool, of which this is more or less a straight conversion.
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
 */
package org.cougaar.util;

//CHANGES: KD - added case sensitive ordering capability
// Made comparison so it doesn't treat spaces as special characters

//CHANGES:
//   set package to "org.cougaar.util"
//   replaced "import java.util.*" with explicit imports,
//   added "main" file reader support

import java.util.Comparator;

/**
 * A sorting comparator to sort strings numerically,
 * ie [1, 2, 10], as opposed to [1, 10, 2].
 */
public final class NaturalOrderComparator<T> implements  Comparator<T> {

    public static final Comparator<String> NUMERICAL_ORDER = new NaturalOrderComparator<String>(false);
    public static final Comparator<String> CASEINSENSITIVE_NUMERICAL_ORDER = new NaturalOrderComparator<String>(true);

    private final boolean caseInsensitive;

    private NaturalOrderComparator(boolean caseInsensitive) {
        this.caseInsensitive = caseInsensitive;
    }

    int compareRight(String a, String b) {
        int bias = 0;
        int ia = 0;
        int ib = 0;

        // The longest run of digits wins.  That aside, the greatest
        // value wins, but we can't know that it will until we've scanned
        // both numbers to know that they have the same magnitude, so we
        // remember it in BIAS.
        for (;; ia++, ib++) {
            char ca = charAt(a, ia);
            char cb = charAt(b, ib);

            if (!Character.isDigit(ca) && !Character.isDigit(cb)) {
                return bias;
            } else if (!Character.isDigit(ca)) {
                return -1;
            } else if (!Character.isDigit(cb)) {
                return +1;
            } else if (ca < cb) {
                if (bias == 0) {
                    bias = -1;
                }
            } else if (ca > cb) {
                if (bias == 0)
                    bias = +1;
            } else if (ca == 0 && cb == 0) {
                return bias;
            }
        }
    }

    public int compare(T o1, T o2) {
        String a = o1.toString();
        String b = o2.toString();

        int ia = 0, ib = 0;
        int nza = 0, nzb = 0;
        char ca, cb;
        int result;

        while (true) {
            // only count the number of zeroes leading the last number compared
            nza = nzb = 0;

            ca = charAt(a, ia);
            cb = charAt(b, ib);

            // skip over leading zeros
            while (ca == '0') {
                if (ca == '0') {
                    nza++;
                } else {
                    // only count consecutive zeroes
                    nza = 0;
                }

                // if the next character isn't a digit, then we've had a run of only zeros
                // we still need to treat this as a 0 for comparison purposes
                if (!Character.isDigit(charAt(a, ia+1)))
                    break;

                ca = charAt(a, ++ia);
            }

            while (cb == '0') {
                if (cb == '0') {
                    nzb++;
                } else {
                    // only count consecutive zeroes
                    nzb = 0;
                }

                // if the next character isn't a digit, then we've had a run of only zeros
                // we still need to treat this as a 0 for comparison purposes
                if (!Character.isDigit(charAt(b, ib+1)))
                    break;

                cb = charAt(b, ++ib);
            }

            // process run of digits
            if (Character.isDigit(ca) && Character.isDigit(cb)) {
                if ((result = compareRight(a.substring(ia), b
                        .substring(ib))) != 0) {
                    return result;
                }
            }

            if (ca == 0 && cb == 0) {
                // The strings compare the same.  Perhaps the caller
                // will want to call strcmp to break the tie.
                return nza - nzb;
            }

            if (ca < cb) {
                return -1;
            } else if (ca > cb) {
                return +1;
            }

            ++ia;
            ++ib;
        }
    }

    private char charAt(String s, int i) {
        if (i >= s.length()) {
            return 0;
        } else {
            return caseInsensitive ? Character.toUpperCase(s.charAt(i)) : s.charAt(i);
        }
    }


}
/*
* 
*
*版权1997-2007 BBNT解决方案有限责任公司
*在国防先进研究项目的赞助下
*美国国防部高级研究计划局(DARPA)。
*
*您可以在下重新分发和/或修改此软件
*发布在
*Cougaar开源网站(www.cougar.org)。
*
*本软件由版权所有者和贡献者提供
*“原样”和任何明示或暗示的保证,包括但不限于
*仅限于对适销性和适用性的默示保证
*不承认有特定目的。在任何情况下,版权
*所有人或出资人应对任何直接、间接、附带的,
*特殊、惩戒性或后果性损害(包括但不限于
*仅限于采购替代货物或服务;失去使用,
*数据或利润;或业务中断),无论是何种原因造成的
*责任理论,无论是合同责任、严格责任还是侵权责任
*(包括疏忽或其他)因使用而产生的
*即使被告知有可能发生此类损坏,也不得使用本软件。
*
* 
*/
/*
java——在java中执行字符串的“自然顺序”比较。
Pierre Luc Paour版权所有(C)2003
基于Martin Pool的C版本,这或多或少是一种直接转换。
Martin Pool版权所有(C)2000
本软件按“原样”提供,无任何明示或暗示
担保在任何情况下,提交人都不对任何损害负责
由于使用本软件而产生的。
允许任何人出于任何目的使用本软件,
包括商业应用程序,并对其进行修改和重新发布
自由,受以下限制:
1.不得歪曲本软件的来源;你不能
声称您编写了原始软件。如果你使用这个软件
在产品中,产品文档中的确认是
感谢,但不是必需的。
2.更改后的源版本必须清楚地标记为这样,并且不得更改
被误传为原始软件。
3.不得从任何源分发中删除或更改此通知。
*/
包org.cougar.util;
//更改:KD-增加区分大小写的订购功能
//进行了比较,因此不会将空格视为特殊字符
//变化:
//将包设置为“org.cougar.util”
//将“import java.util.*”替换为显式导入,
//添加了“主”文件读取器支持
导入java.util.Comparator;
/**
*对字符串进行数字排序的排序比较器,
*即[1,2,10],而不是[1,10,2]。
*/
公共最终类NaturalOrderComparator实现了Comparator{
/*
 * <copyright>
 *
 *  Copyright 1997-2007 BBNT Solutions, LLC
 *  under sponsorship of the Defense Advanced Research Projects
 *  Agency (DARPA).
 *
 *  You can redistribute this software and/or modify it under the
 *  terms of the Cougaar Open Source License as published on the
 *  Cougaar Open Source Website (www.cougaar.org).
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * </copyright>
 */
/*
NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
Copyright (C) 2003 by Pierre-Luc Paour <natorder@paour.com>

Based on the C version by Martin Pool, of which this is more or less a straight conversion.
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
 */
package org.cougaar.util;

//CHANGES: KD - added case sensitive ordering capability
// Made comparison so it doesn't treat spaces as special characters

//CHANGES:
//   set package to "org.cougaar.util"
//   replaced "import java.util.*" with explicit imports,
//   added "main" file reader support

import java.util.Comparator;

/**
 * A sorting comparator to sort strings numerically,
 * ie [1, 2, 10], as opposed to [1, 10, 2].
 */
public final class NaturalOrderComparator<T> implements  Comparator<T> {

    public static final Comparator<String> NUMERICAL_ORDER = new NaturalOrderComparator<String>(false);
    public static final Comparator<String> CASEINSENSITIVE_NUMERICAL_ORDER = new NaturalOrderComparator<String>(true);

    private final boolean caseInsensitive;

    private NaturalOrderComparator(boolean caseInsensitive) {
        this.caseInsensitive = caseInsensitive;
    }

    int compareRight(String a, String b) {
        int bias = 0;
        int ia = 0;
        int ib = 0;

        // The longest run of digits wins.  That aside, the greatest
        // value wins, but we can't know that it will until we've scanned
        // both numbers to know that they have the same magnitude, so we
        // remember it in BIAS.
        for (;; ia++, ib++) {
            char ca = charAt(a, ia);
            char cb = charAt(b, ib);

            if (!Character.isDigit(ca) && !Character.isDigit(cb)) {
                return bias;
            } else if (!Character.isDigit(ca)) {
                return -1;
            } else if (!Character.isDigit(cb)) {
                return +1;
            } else if (ca < cb) {
                if (bias == 0) {
                    bias = -1;
                }
            } else if (ca > cb) {
                if (bias == 0)
                    bias = +1;
            } else if (ca == 0 && cb == 0) {
                return bias;
            }
        }
    }

    public int compare(T o1, T o2) {
        String a = o1.toString();
        String b = o2.toString();

        int ia = 0, ib = 0;
        int nza = 0, nzb = 0;
        char ca, cb;
        int result;

        while (true) {
            // only count the number of zeroes leading the last number compared
            nza = nzb = 0;

            ca = charAt(a, ia);
            cb = charAt(b, ib);

            // skip over leading zeros
            while (ca == '0') {
                if (ca == '0') {
                    nza++;
                } else {
                    // only count consecutive zeroes
                    nza = 0;
                }

                // if the next character isn't a digit, then we've had a run of only zeros
                // we still need to treat this as a 0 for comparison purposes
                if (!Character.isDigit(charAt(a, ia+1)))
                    break;

                ca = charAt(a, ++ia);
            }

            while (cb == '0') {
                if (cb == '0') {
                    nzb++;
                } else {
                    // only count consecutive zeroes
                    nzb = 0;
                }

                // if the next character isn't a digit, then we've had a run of only zeros
                // we still need to treat this as a 0 for comparison purposes
                if (!Character.isDigit(charAt(b, ib+1)))
                    break;

                cb = charAt(b, ++ib);
            }

            // process run of digits
            if (Character.isDigit(ca) && Character.isDigit(cb)) {
                if ((result = compareRight(a.substring(ia), b
                        .substring(ib))) != 0) {
                    return result;
                }
            }

            if (ca == 0 && cb == 0) {
                // The strings compare the same.  Perhaps the caller
                // will want to call strcmp to break the tie.
                return nza - nzb;
            }

            if (ca < cb) {
                return -1;
            } else if (ca > cb) {
                return +1;
            }

            ++ia;
            ++ib;
        }
    }

    private char charAt(String s, int i) {
        if (i >= s.length()) {
            return 0;
        } else {
            return caseInsensitive ? Character.toUpperCase(s.charAt(i)) : s.charAt(i);
        }
    }


}
public static List<String> sortAsNumbers(Collection<String> collection) {
    return collection
            .stream()
            .map(Integer::valueOf)
            .sorted()
            .map(String::valueOf)
            .collect(Collectors.toList());
}
static final Comparator<Object> COMPARADOR = new Comparator<Object>() {
    public int compare(Object o1, Object o2) {
        double numero1;
        double numero2;
        try {
            numero1 = Double.parseDouble(o1.toString());
            numero2 = Double.parseDouble(o2.toString());
            return Double.compare(numero1, numero2);
        } catch (Exception e) {
            return o1.toString().compareTo(o2.toString());
        }
    }
};