Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中按字符优先排序_Java_Sorting - Fatal编程技术网

Java中按字符优先排序

Java中按字符优先排序,java,sorting,Java,Sorting,我需要对列表进行排序,以便所有以char开头的字符串都先按以number开头的字符串升序排序。是否有任何内置算法可以做到这一点?如果没有,解决这个问题的最佳方法是什么 Doctor Review 3rd Party Contact Appointment 24-Hour Service Doctor Preparation 到 我正在尝试编写自定义比较器,但不确定如何对以字符和数字开头的字符串进行分组。您可以定义自己的字符串(请参见下面代码中的myrules) 这种方法也适用于第一个位置之后的

我需要对列表进行排序,以便所有以char开头的字符串都先按以number开头的字符串升序排序。是否有任何内置算法可以做到这一点?如果没有,解决这个问题的最佳方法是什么

Doctor Review
3rd Party Contact
Appointment
24-Hour Service
Doctor Preparation

我正在尝试编写自定义比较器,但不确定如何对以字符和数字开头的字符串进行分组。

您可以定义自己的字符串(请参见下面代码中的
myrules

这种方法也适用于第一个位置之后的数字

    List<String> list = new ArrayList<String>();
    list.add("Doctor Review");
    list.add("Doctor Review A"); // check sort order of this entry!
    list.add("Doctor Review 1"); // check sort order of this entry!
    list.add("3rd Party Contact");
    list.add("Appointment");
    list.add("24-Hour Service");
    list.add("Doctor Preparation");

    String myrules = "< a, A < b, B < c, C < d, D < e, E < f, F < g, G < h, H < i, I" +
        "< j, J < k, K < l, L < m, M < n, N < o, O < p, P < q, Q < r, R" +
        "< s, S < t, T < u, U < v, V < w, W < x, X < y, Y < z, Z" +
        "< 0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9";

    try {
      RuleBasedCollator myRuleBasedCollator = new RuleBasedCollator(myrules);
      Collections.sort(list, myRuleBasedCollator);
      for (String s : list) {
        System.out.println(s);
      }
    } catch (ParseException e) {
      e.printStackTrace();
    }

正如您所猜测的,需要一个自定义的
比较器

现在,您将遇到的困难是使用ASCII集合之外的字符;特别是,由于Java在内部将文本数据存储为UTF-16代码单元,BMP之外的任何内容都将是两个字符

但让我们说,这不是一个问题,你唯一关心的是“古老的”阿拉伯数字,它恰好可以用一个
字符
表示

那么这就是如何编写这样一个比较器(未经测试!):

公共静态最终比较器阿拉伯数字最后比较器
=新的比较器()
{
@凌驾
公共整数比较(最终字符串o1,最终字符串o2)
{
返回doCompare(CharBuffer.wrap(o1),CharBuffer.wrap(o2));
}
专用int文件包(最终字符缓冲区buf1,最终字符缓冲区buf2)
{
//测试每个缓冲器的空度
final int r1=buf1.remaining();
最终整数r2=buf2.剩余();
如果(r1==0)
返回r2==0?0:-1;
如果(r2==0)
return 1;//我们知道r1在这里不是空的
//从两个缓冲区抓取第一个字符
final char c1=buf1.get();
final char c2=buf2.get();
//如果两个字符相同,我们必须继续
如果(c1==c2)
返回文件(buf1、buf2);
//它们不是…测试它们是否是数字
最终布尔值oneIsDigit=字符.isDigit(c1);
最终布尔值twoIsDigit=字符.isDigit(c2);
//两者都是数字:返回合同期望的内容
如果(一个数字和两个数字)
返回c1-c2;
//从这一点上,我们知道至少有一个字符是
//没有一个数字,而且它们都是不同的。
如果(oneIsDigit)
返回1;
if(twoIsDigit)
返回-1;
//两者都不是数字,但我们知道它们是不同的:
//只需退还差额
返回c1-c2;
}
}
}
这个怎么样

public class TryMe {
  public static void main(String[] args) {
    List<String> sortMe = new ArrayList<>();
    sortMe.add("Doctor Review");
    sortMe.add("3rd Party Contact");
    sortMe.add("Appointment");
    sortMe.add("24-Hour Service");
    sortMe.add("Doctor Preparation");
    Collections.sort(sortMe, new MyComparator());
    System.out.println(sortMe);
  }

  private static class MyComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
      if (Character.isDigit(o1.charAt(0))) {
        if (Character.isDigit(o2.charAt(0))) {
          //replace here with "return o1.compareTo(o2)" for original
          int i1 = getFirstDigits(o1);
          int i2 = getFirstDigits(o2);
          if (i1 == i2) return o1.compareTo(o2);
          return i1 - i2;
        } else {
          return 1;
        }
      }
      if (Character.isDigit(o2.charAt(0))) return -1;
      return o1.compareTo(o2);
    }
  }

  private static int getFirstDigits(String from) {
    int i = 0;
    for (i = 0 ; i < from.length() ; i++) {
      if (!Character.isDigit(from.charAt(i))) {
        return Integer.parseInt(from.substring(0, i));
      }
    }
    if (i > 0) return Integer.parseInt(from.substring(0, i));
    throw new IllegalArgumentException("No digits to parse, should not happen");
  }
}
公共类TryMe{
公共静态void main(字符串[]args){
List sortMe=new ArrayList();
增加(“医生回顾”);
排序添加(“第三方联系人”);
sortMe.添加(“任命”);
添加(“24小时服务”);
sortMe.添加(“医生制剂”);
Collections.sort(sortMe,newmycomparator());
System.out.println(sortMe);
}
私有静态类MyComparator实现Comparator{
@凌驾
公共整数比较(字符串o1、字符串o2){
if(Character.isDigit(o1.charAt(0))){
if(Character.isDigit(o2.charAt(0))){
//此处替换为“返回o1.比较(o2)”作为原始
int i1=getFirstDigits(o1);
int i2=获取第一个数字(o2);
如果(i1==i2)返回o1,与(o2)比较;
返回i1-i2;
}否则{
返回1;
}
}
if(Character.isDigit(o2.charAt(0)))返回-1;
返回o1。与(o2)相比;
}
}
私有静态int getFirstDigits(字符串来自){
int i=0;
对于(i=0;i0)返回Integer.parseInt(来自.substring(0,i));
抛出新的IllegalArgumentException(“没有要解析的数字,不应该发生”);
}
}
ArrayList list=new ArrayList();
列表。添加(“医生审查”);
列表。添加(“第三方联系人”);
列表。添加(“任命”);
列表。添加(“24小时服务”);
列表。添加(“医生制剂”);
ArrayList newlist=新的ArrayList();
集合。排序(列表);
for(字符串x:列表)
{
如果(!Character.isDigit(x.charAt(0))){
新增(x);
}
}
for(字符串x:列表)
{
if(Character.isDigit(x.charAt(0))){
新增(x);
}
}

解决方案,使用另一个列表

没有内置算法,没有,但您可以编写自定义的
比较器。另外,对于ASCII集合之外的字符应该怎么办?你可以找到这样一个比较器的例子,它将按字母和数字进行排序。我将研究编写一个自定义的
比较器
类,就像@fge所说的。你希望以什么顺序
第二行
十条戒律
sorted?这只是您关心的第一个
char
,还是希望保留整个字符串比较的模式?
second Chance
是在
22次机会之前还是之后出现的呢?
不错,但这是高度依赖于区域设置的(通常是字符串排序),我不明白为什么要执行递归调用。如果第一个字符相同,为什么我们需要检查第二个字符?我想我们只需要知道第一个字符是否是数字,以及如何将其与第二个字符串的第一个数字进行比较。如果我看得正确,你的代码已经正确了。如果第一个代码相同,我们仍然需要比较第二个和更进一步,对吗?请注意,我知道这段代码并不理想……“如果第一段代码相同,我们仍然需要比较第二段代码,然后再进一步比较,对吗?”是的,但正常的字符串比较可以
Appointment
Doctor Preparation
Doctor Review
Doctor Review A
Doctor Review 1
24-Hour Service
3rd Party Contact
public static final Comparator<String> ARABIC_NUMBERS_LAST_COMPARATOR
    = new Comparator<String>()
    {
        @Override
        public int compare(final String o1, final String o2)
        {
            return doCompare(CharBuffer.wrap(o1), CharBuffer.wrap(o2));
        }

        private int doCompare(final CharBuffer buf1, final CharBuffer buf2)
        {
            // Test for the emptiness of each buffer
            final int r1 = buf1.remaining();
            final int r2 = buf2.remaining();
            if (r1 == 0)
                return r2 == 0 ? 0 : -1;
            if (r2 == 0)
                return 1; // we know that r1 is not empty here

            // Grab the first character from both buffers
            final char c1 = buf1.get();
            final char c2 = buf2.get();

            // If both characters are the same we must continue
            if (c1 == c2)
                return doCompare(buf1, buf2);

            // They are not... Test whether either of them is a digit
            final boolean oneIsDigit = Character.isDigit(c1);
            final boolean twoIsDigit = Character.isDigit(c2);

            // Both are digits: return what the contract expects
            if (oneIsDigit && twoIsDigit)
                return c1 - c2;

            // From this point on we know that at least one character is
            // not a digit, and that they are both different.
            if (oneIsDigit)
                return 1;
            if (twoIsDigit)
                return -1;
            // Both are not digits, but we know them to be different:
            // just return the difference
            return c1 - c2;
        }
    }
}
public class TryMe {
  public static void main(String[] args) {
    List<String> sortMe = new ArrayList<>();
    sortMe.add("Doctor Review");
    sortMe.add("3rd Party Contact");
    sortMe.add("Appointment");
    sortMe.add("24-Hour Service");
    sortMe.add("Doctor Preparation");
    Collections.sort(sortMe, new MyComparator());
    System.out.println(sortMe);
  }

  private static class MyComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
      if (Character.isDigit(o1.charAt(0))) {
        if (Character.isDigit(o2.charAt(0))) {
          //replace here with "return o1.compareTo(o2)" for original
          int i1 = getFirstDigits(o1);
          int i2 = getFirstDigits(o2);
          if (i1 == i2) return o1.compareTo(o2);
          return i1 - i2;
        } else {
          return 1;
        }
      }
      if (Character.isDigit(o2.charAt(0))) return -1;
      return o1.compareTo(o2);
    }
  }

  private static int getFirstDigits(String from) {
    int i = 0;
    for (i = 0 ; i < from.length() ; i++) {
      if (!Character.isDigit(from.charAt(i))) {
        return Integer.parseInt(from.substring(0, i));
      }
    }
    if (i > 0) return Integer.parseInt(from.substring(0, i));
    throw new IllegalArgumentException("No digits to parse, should not happen");
  }
}
   ArrayList<String> list = new ArrayList<String>();
    list.add("Doctor Review");
    list.add("3rd Party Contact");
    list.add("Appointment");
    list.add("24-Hour Service");
    list.add("Doctor Preparation");
    ArrayList<String> newlist = new ArrayList<>();
    Collections.sort(list);
    for (String x : list)

    {
        if (!Character.isDigit(x.charAt(0))) {
            newlist.add(x);
        }
    }

    for (String x : list)

    {
        if (Character.isDigit(x.charAt(0))) {
            newlist.add(x);
        }
    }