如何按字典顺序对 ArrayList 进行排序?

发布于 2024-09-04 13:39:38 字数 207 浏览 6 评论 0原文

我正在尝试对表示卡值的字符串 ArrayList 进行排序。因此,有些卡片包含字母(“King”),有些卡片包含仅包含数字(“7”)的字符串。我知道使用 Collections.sort,但它只对包含字母的字符串进行排序。如何让 ArrayList 按数字和字母顺序排序?

编辑:抱歉,我在查看排序时一定没有太注意。排序工作正常,我一定是因为 10 会出现在 2 之前而感到困惑。谢谢

I am trying to sort an ArrayList of Strings that represent card values. So, some cards contain letters ("King") and some contain Strings containing only a number ("7"). I know to use Collections.sort, but it only sorts Strings that contain letters. How do I get the ArrayList to be sorted by number as well as alphabetically?

Edit: Sorry, I must not have been paying much attention when I looked at the sorting. The sort works correctly, I must have just been thrown off by the fact that a 10 will come before a 2. Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

阳光①夏 2024-09-11 13:39:39

不,Collections.sort 将使用 Unicode 序数词典比较对所有内容进行排序,因为这是 String.compareTo。 “7”将出现在“King”之前,“10”将出现在“2”之前。

No, Collections.sort will sort everything, using an Unicode ordinal lexicographic comparison as that's the behaviour of String.compareTo. "7" will come before "King", and "10" will come before "2".

寂寞美少年 2024-09-11 13:39:39

据我了解,您有一个像 ["7", "Queen", "9", "6"] 这样的数组,并且您希望它看起来像 ["Queen", "9 ", "7", "6"](或按相反顺序)排序完成后。

我建议使其更加面向对象,即创建带有字段名称和值的类卡:

class Card {
   private final String name;
   private final int value;
   ...
   //constructor and getters
}

然后以这种方式创建实例:

Card six = new Card("6", 6);
Card ten = new Card("10", 10);
Card queen = new Card("Queen", 12);

之后,使用卡进行所有操作(尤其是排序)会更容易)使用字段 value 代替卡片名称。

As I understand, you have an array like ["7", "Queen", "9", "6"] and you want it to look like ["Queen", "9", "7", "6"] (or in reverse order) after sorting is done.

I'd recommend to make it a bit more object-oriented i.e. create class Card with fields name and value:

class Card {
   private final String name;
   private final int value;
   ...
   //constructor and getters
}

and after that create instances in this manner:

Card six = new Card("6", 6);
Card ten = new Card("10", 10);
Card queen = new Card("Queen", 12);

After that it'll be much easier to make all operations with cards (and sorting particularly) using field value instead of cards' names.

平安喜乐 2024-09-11 13:39:39

正如 @Jon Skeet 所说,内置排序将根据 Unicode 值进行比较。您必须编写自己的排序方法。

不过,只要您编写自己的代码,我是否可以建议进行枚举?一副纸牌是使用枚举的典型示例之一。简而言之,您可以为一组事物声明自己的排序顺序;如果你愿意的话,你甚至可以让黑桃 K 的排名超过方块 K。 此处查看 Sun 的教程。

As @Jon Skeet said, the built-in sort will compare based on Unicode values. You'd have to write your own sorting method.

As long as you're writing your own code, though, might I suggest an enumeration? A deck of cards is one of the canonical examples for use of enums. The short version is that you can declare your own sort order for a group of things; you could even make the king of spades outrank the king of diamonds, if you wanted. Check out Sun's tutorial here.

独行侠 2024-09-11 13:39:39

我知道使用 Collections.sort,但它只对包含字母的字符串进行排序。如何让 ArrayList 按数字和字母顺序排序?

如果字符串是数字,则它已经被排序(虽然作为字符串),看看:

import java.util.*;
class Sort {
    public static void main( String [] args  ) {
        List list = Arrays.asList("Kings","7", "Abcd", "3.1416");
        Collections.sort( list );
        System.out.println( list );
    }
}

打印

$ java Sort
[3.1416, 7, Abcd, Kings]

这是您需要的吗?

编辑

假设(猜测)您需要对一副卡片进行排序,其中既有数字又有“字母”(J、Q、K、A),您可以尝试使用自定义比较器。

这是将数字“视为数字”,其余视为字符串的一个,因此“10”位于“2”之后但在“Kings”之前,

import java.util.*;
class Sort {
    public static void main( String [] args  ) {

        List<String> list = Arrays.asList("Kings","7", "Queen", "3", "10", "A", "2", "8", "Joker");
        Collections.sort( list , new Comparator<String>(){
            public int compare( String a, String b ){
                // if both are numbers
                if( a.matches("\\d+") && b.matches("\\d+")) {
                    return new Integer( a ) - new Integer( b );
                }
                // else, compare normally. 
                return a.compareTo( b );
            }
        });
        System.out.println( list );
    }
}

$ java Sort
[2, 3, 7, 8, 10, A, Joker, Kings, Queen]

如果这就是您所需要的,我想这将帮助您找出其余部分。也许接下来的事情就是如何对黑桃和红心进行排序。

按照 Roman 的答案,您可以创建一个类并实现 Comparable 接口:

  class Card implements Comparable<Card> {
       public int compareTo( Card other ) {  
           // add custom logic to compare one card with other 
       }
   }

I know to use Collections.sort, but it only sorts Strings that contain letters. How do I get the ArrayList to be sorted by number as well as alphabetically?

If the string is a number it is already being sorted ( as an String though ) look:

import java.util.*;
class Sort {
    public static void main( String [] args  ) {
        List list = Arrays.asList("Kings","7", "Abcd", "3.1416");
        Collections.sort( list );
        System.out.println( list );
    }
}

Prints

$ java Sort
[3.1416, 7, Abcd, Kings]

Is that what you need?

edit

Assuming ( guessing ) what you need is to sort a deck of cards, which have both numbers and "letters" ( J, Q, K, A ) you may try to use a custom comparator.

Here's one that takes into consideration the numbers "as numbers" the the rest as strings, so "10" comes after "2" but before "Kings"

import java.util.*;
class Sort {
    public static void main( String [] args  ) {

        List<String> list = Arrays.asList("Kings","7", "Queen", "3", "10", "A", "2", "8", "Joker");
        Collections.sort( list , new Comparator<String>(){
            public int compare( String a, String b ){
                // if both are numbers
                if( a.matches("\\d+") && b.matches("\\d+")) {
                    return new Integer( a ) - new Integer( b );
                }
                // else, compare normally. 
                return a.compareTo( b );
            }
        });
        System.out.println( list );
    }
}

$ java Sort
[2, 3, 7, 8, 10, A, Joker, Kings, Queen]

If that's what you need I guess this would help you to figure out the rest. Probably the next thing would be how to sort spades vs. hearts.

Following the answer by Roman you could create a class and implement the Comparable interface:

  class Card implements Comparable<Card> {
       public int compareTo( Card other ) {  
           // add custom logic to compare one card with other 
       }
   }
不离久伴 2024-09-11 13:39:39

排序将根据您的字符集对所有内容进行排序。换句话说,按照字典顺序,所有数字都将出现在字母之前。例如,十进制数字以“.”开头并且按字典顺序乱序。

如果您想更改此设置,请创建 Comparator 对象。然后您可以按照您喜欢的任何顺序放置这些项目。

例如,这将按数字顺序对数字进行排序,也会按词汇顺序对单词进行排序:

class CardComparator extends Object implements Comparator{
 public int compare(Object a, Object b){
  try{
   double d1=Double.valueOf(a.toString());
   try{
     double d2=Double.valueOf(b.toString());
     return (d2>d1)?1:-1;            // both numeric
   }catch(NumberFormatException e){ // a is numeric but b isn't
     return 1;
   }
  }catch(NumberFormatException e){  
    try{
     double d2=Double.valueOf(b.toString()); 
     return -1;                       // a is nonnumeric but b is
    }catch(NumberFormatException e){  // both nonnumeric
      return a.toString().compareTo(b.toString);
    }
  }
 }
}
Comparator comparator=new CardComparator();
Collections.sort(cards, comparator);

PS 未测试!

Sort will sort everything according to your charset. In otherwords, all numbers will come before letters in the lexicographic order. For example, decimal numbers start with a '.' and out of order lexicographically.

If you want to change this, make Comparator object. You could then put the items in whatever order you like.

For example, this will sort numbers in numerical order, and also words in lexical order:

class CardComparator extends Object implements Comparator{
 public int compare(Object a, Object b){
  try{
   double d1=Double.valueOf(a.toString());
   try{
     double d2=Double.valueOf(b.toString());
     return (d2>d1)?1:-1;            // both numeric
   }catch(NumberFormatException e){ // a is numeric but b isn't
     return 1;
   }
  }catch(NumberFormatException e){  
    try{
     double d2=Double.valueOf(b.toString()); 
     return -1;                       // a is nonnumeric but b is
    }catch(NumberFormatException e){  // both nonnumeric
      return a.toString().compareTo(b.toString);
    }
  }
 }
}
Comparator comparator=new CardComparator();
Collections.sort(cards, comparator);

PS not tested!

软的没边 2024-09-11 13:39:39
Sharing an example where I have created two comparator for Lexicographical order, one for Integers and other for String
Note: String by default support Lexicographical order 

import java.util.*;

public class ArrayListLexicographicalSort {

    public static void main(String[] args) {

        //Comparator for Lexicographical order for Integer
        Comparator<Integer> comparator = (i,j)->ArrayListLexicographicalSort.lexicographicalSort(i,j);
        //Comparator for Lexicographical order for String
        Comparator<String> stringComparator = (i,j)->i.compareTo(j);

        //list of integers
       List<Integer> integerList = Arrays.asList(101,11,2,100,10);
        System.out.println(integerList);
        //o/p->[101, 11, 2, 100, 10]
        //creating a treeset with Lexicographical sort order for Integer
        TreeSet<Integer> integerTreeSet = new TreeSet<>(comparator);
        integerTreeSet.addAll(integerList);
        //resultant Lexicographical order for integers
        System.out.println(integerTreeSet);
        //o/p->[10, 100, 101, 11, 2]

        //list of Strings
        List<String> stringList = Arrays.asList("Abhinav","Kumar","Aabhinav","101","100","2");
        System.out.println(stringList);
        //o/p->[Abhinav, Kumar, Aabhinav, 101, 100, 2]
        //creating a treeset with Lexicographical sort order for String
        TreeSet<String> stringTreeSet = new TreeSet<>(stringComparator);
        stringTreeSet.addAll(stringList);
        //resultant Lexicographical order for strings
        System.out.println(stringTreeSet);
        //o/p->[100, 101, 2, Aabhinav, Abhinav, Kumar]
    }

   // method to compare two integer lexicographically
    private static int lexicographicalSort(long input1, long input2){

        // -ve means input1 is smaller
        //  +ve means input1 is larger
        //  0 means input1 and input2 are same
        long inp1 = input1;
        long inp2 = input2;
        int input1Length = 1;
        int input2Length = 1;

        while(inp1/10>0){
            input1Length++;
            inp1 = inp1/10;
        }

        while(inp2/10>0){
            input2Length++;
            inp2 = inp2/10;
        }

        int[] inArr1 = new int[input1Length];
        int[] inArr2 = new int[input2Length];

        inp1 = input1;
        inp2 = input2;

        int min = Math.min(input1Length,input2Length);

        while(inp1/10>0){
            inArr1[--input1Length] = (int)inp1%10;
            inp1 = inp1/10;
        }
        inArr1[--input1Length] = (int)inp1;

        while(inp2/10>0){
            inArr2[--input2Length] = (int)inp2%10;
            inp2 = inp2/10;
        }
        inArr2[--input2Length] = (int)inp2;

        int k = 0;

        while(k<min){
            if( inArr1[k] != inArr2[k]){
                return inArr1[k]-inArr2[k];
            }
            k++;
        }

        return inArr1.length-inArr2.length;
    }
}
Sharing an example where I have created two comparator for Lexicographical order, one for Integers and other for String
Note: String by default support Lexicographical order 

import java.util.*;

public class ArrayListLexicographicalSort {

    public static void main(String[] args) {

        //Comparator for Lexicographical order for Integer
        Comparator<Integer> comparator = (i,j)->ArrayListLexicographicalSort.lexicographicalSort(i,j);
        //Comparator for Lexicographical order for String
        Comparator<String> stringComparator = (i,j)->i.compareTo(j);

        //list of integers
       List<Integer> integerList = Arrays.asList(101,11,2,100,10);
        System.out.println(integerList);
        //o/p->[101, 11, 2, 100, 10]
        //creating a treeset with Lexicographical sort order for Integer
        TreeSet<Integer> integerTreeSet = new TreeSet<>(comparator);
        integerTreeSet.addAll(integerList);
        //resultant Lexicographical order for integers
        System.out.println(integerTreeSet);
        //o/p->[10, 100, 101, 11, 2]

        //list of Strings
        List<String> stringList = Arrays.asList("Abhinav","Kumar","Aabhinav","101","100","2");
        System.out.println(stringList);
        //o/p->[Abhinav, Kumar, Aabhinav, 101, 100, 2]
        //creating a treeset with Lexicographical sort order for String
        TreeSet<String> stringTreeSet = new TreeSet<>(stringComparator);
        stringTreeSet.addAll(stringList);
        //resultant Lexicographical order for strings
        System.out.println(stringTreeSet);
        //o/p->[100, 101, 2, Aabhinav, Abhinav, Kumar]
    }

   // method to compare two integer lexicographically
    private static int lexicographicalSort(long input1, long input2){

        // -ve means input1 is smaller
        //  +ve means input1 is larger
        //  0 means input1 and input2 are same
        long inp1 = input1;
        long inp2 = input2;
        int input1Length = 1;
        int input2Length = 1;

        while(inp1/10>0){
            input1Length++;
            inp1 = inp1/10;
        }

        while(inp2/10>0){
            input2Length++;
            inp2 = inp2/10;
        }

        int[] inArr1 = new int[input1Length];
        int[] inArr2 = new int[input2Length];

        inp1 = input1;
        inp2 = input2;

        int min = Math.min(input1Length,input2Length);

        while(inp1/10>0){
            inArr1[--input1Length] = (int)inp1%10;
            inp1 = inp1/10;
        }
        inArr1[--input1Length] = (int)inp1;

        while(inp2/10>0){
            inArr2[--input2Length] = (int)inp2%10;
            inp2 = inp2/10;
        }
        inArr2[--input2Length] = (int)inp2;

        int k = 0;

        while(k<min){
            if( inArr1[k] != inArr2[k]){
                return inArr1[k]-inArr2[k];
            }
            k++;
        }

        return inArr1.length-inArr2.length;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文