【问题标题】:Sorting 2D array of strings in Java在Java中对二维字符串数组进行排序
【发布时间】:2011-07-01 03:29:06
【问题描述】:

我知道以前可能有人问过这个问题,但我找不到合适的答案。所以说我有这个数组:

String[][] theArray = {
        {"james", "30.0"},
        {"joyce", "35.0"},
        {"frank", "3.0"},
        {"zach", "34.0"}};

有没有办法按每个子元素的第二个元素对这个数组进行降序排序。所以我会得到这样的东西。

theArray = {
        {"joyce", "35.0"},
        {"zach", "34.0"},
        {"james", "30.0"},
        {"frank", "3.0"}};

【问题讨论】:

    标签: java arrays string sorting multidimensional-array


    【解决方案1】:
    /**
         *
         * @param array - 2D array required to be arranged by certain column
         * @param columnIndex - starts from 0; this will be the main comparator
         * @param hasHeaders - true/false; true - ignore the first row. False -
         * first row it's also compared and arranged
         * @return - the new arranged array
         */
        private String[][] arrangeArray(String[][] array, int columnIndex, boolean hasHeaders) {
            int headersExists = 0;
            if (hasHeaders) {
                headersExists = 1;
            }
            for (int i = headersExists; i < array.length; i++) {
                for (int j = headersExists; j < array.length; j++) {
                if (array[i][columnIndex].compareTo(array[j][columnIndex]) < 0){
                    String[] temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
        }
        return array;
    }
    

    【讨论】:

      【解决方案2】:

      public static void main(String[] args) {

      String Name[][]={{"prakash","kumar"},{"raj","kappor"},{"vinod","bhart"}};
      
      String str[]=new String[2];
      
      
      for(int j=0; j<Name.length;j++)
       {
           for (int i=0 ; i<2; i++)
           {
               str[i]=Name[j][i];
           }
       for(int i=0;i<str.length;i++)
       {
           for(int k=i+1;k<str.length;k++)
           {
               if(str[i].compareTo(str[k])>0)
               {
                   String temp= str[i];
                   str[i]=str[k];
                   str[k]=temp;
               }
      
               }
           System.out.print(str[i]+ " ");
        }
       System.out.println();
       }
      
      
      
       }
      }
      

      【讨论】:

        【解决方案3】:

        您必须使用Arrays.sort() method。此方法采用Comparator 作为参数。 sort 方法委托给比较器来确定数组的一个元素是否必须被认为大于、小于或等于另一个元素。由于外部数组的每个元素都是一个数组,因此比较器必须比较(字符串的)数组。

        必须根据第二个元素的值来比较数组。第二个元素是一个字符串,它实际上代表一个双数。因此,您必须将字符串转换为数字,否则顺序将按字典顺序排列(20 在 3 之前)而不是数字。

        比较器可能看起来像这样:

        public class StrinArrayComparator implements Comparator<String[]> {
            @Override
            public int compare(String[] array1, String[] array2) {
                // get the second element of each array, andtransform it into a Double
                Double d1 = Double.valueOf(array1.[1]);
                Double d2 = Double.valueOf(array2.[1]);
                // since you want a descending order, you need to negate the 
                // comparison of the double
                return -d1.compareTo(d2);
                // or : return d2.compareTo(d1);
            }
        }
        

        【讨论】:

          【解决方案4】:

          如果您想摆脱数组,这里有一个使用List&lt;Record&gt;RecordComparator 的变体implements Comparator&lt;Record&gt;

          控制台:

          乔伊斯 35.0 扎克 34.0 詹姆斯 30.0 坦率 23.0

          代码:

          import java.util.ArrayList;
          import java.util.Arrays;
          import java.util.Collections;
          import java.util.Comparator;
          import java.util.List;
          
          /** @see http://stackoverflow.com/questions/5064027 */
          public class ComparatorTest {
              public static void main(String[] args) {
                  List<Record> list = new ArrayList<Record>(Arrays.asList(
                      new Record("james", "30.0"),
                      new Record("joyce", "35.0"),
                      new Record("frank", "23.0"),
                      new Record("zach",  "34.0")));
                  print(list, Sort.DESCENDING, Field.D);
              }
          
              private static void print(List<Record> list, Sort s, Field f) {
                  RecordComparator rc = new RecordComparator(s, f);
                  Collections.sort(list, rc);
                  for (Record r : list) {
                      System.out.println(r);
                  }
              }
          }
          
          class Record {
          
              private String s;
              private Double d;
          
              public Record(String name, String number) {
                  this.s = name;
                  this.d = Double.valueOf(number);
              }
          
              @Override
              public String toString() {
                  return s + " " + d;
              }
          
              public int compareTo(Field field, Record record) {
                  switch (field) {
                      case S: return this.s.compareTo(record.s);
                      case D: return this.d.compareTo(record.d);
                      default: throw new IllegalArgumentException(
                          "Unable to sort Records by " + field.getType());
                  }
              }
          }
          
          enum Sort { ASCENDING, DESCENDING; }
          
          enum Field {
          
              S(String.class), D(Double.class);
          
              private Class type;
          
              Field(Class<? extends Comparable> type) {
                  this.type = type;
              }
          
              public Class getType() {
                  return type;
              }
          }
          
          class RecordComparator implements Comparator<Record> {
          
              private Field field;
              private Sort sort;
          
              public RecordComparator(Sort sort, Field field) {
                  this.sort = sort;
                  this.field = field;
              }
          
              @Override
              public final int compare(Record a, Record b) {
                  int result = a.compareTo(field, b);
                  if (sort == Sort.ASCENDING) return result;
                  else return -result;
              }
          }
          

          【讨论】:

            【解决方案5】:

            您似乎住在object denial。这些内部数组看起来很像关于 Person 的信息(带有名称和一些值,可能是分数)。

            您要做的是编写一个自定义类来保存该信息:

            public class Person {
              private final String name;
              private final double score;
            
              public Person(final String name, final double score) {
                this.name=name;
                this.score=score;
              }
            
              public String getName() {
                return name;
              }
            
              public double getScore() {
                return score;
              }
            }
            

            然后,当您想要对它们进行排序时,您只需实现一个 Comparator&lt;Person&gt; 来指定您希望它们如何排序:

            public PersonScoreComparator implements Comparator<Person> {
              public int compare(Person p1, Person p2) {
                return Double.compare(p1.getScore(), p2.getScore());
              }
            }
            

            或者,您可以通过添加此方法让Person 类本身实现Comparable&lt;Person&gt;

            public int compareTo(Person other) {
              return Double.compare(getScore(), other.getScore());
            }
            

            【讨论】:

            • 是的,我想自己写,但我选择回答字面问题。 +1 最佳实践
            【解决方案6】:

            Arrays.sort(arr, comparator) 与自定义比较器一起使用:

            Arrays.sort(theArray, new Comparator<String[]>(){
            
                @Override
                public int compare(final String[] first, final String[] second){
                    // here you should usually check that first and second
                    // a) are not null and b) have at least two items
                    // updated after comments: comparing Double, not Strings
                    // makes more sense, thanks Bart Kiers
                    return Double.valueOf(second[1]).compareTo(
                        Double.valueOf(first[1])
                    );
                }
            });
            System.out.println(Arrays.deepToString(theArray));
            

            输出:

            [[乔伊斯,35.0],[扎克,34.0],[詹姆斯,30.0],[弗兰克,23.0]]


            小心:

            您将对传入的数组进行排序,Arrays.sort() 不会返回新数组(实际上它返回 void)。如果您想要排序后的副本,请执行以下操作:

            String[][] theCopy = Arrays.copyOf(theArray, theArray.length);
            

            并在theCopy 上执行排序,而不是theArray

            【讨论】:

            • @Bart 现在将其添加到我的答案中
            • 它适用于具有相同位数的数字。因为我有从 0.0 到 9.0 的数字,所以它以这种方式排序:0.0、1.0、10.0。 11.0、15.0、2.0、23.0、3.0、32.0
            • @Julio 我刚刚改变了我的答案。您是否尝试过比较 Double 值的当前版本?
            【解决方案7】:

            java.util.Arrays 中有几种排序方法。其中两个采用自定义Comparators。只需提供一个比较内部数组的第二个元素的比较器。

            【讨论】:

              【解决方案8】:

              -使用 Arrays.toList() 从这个数组中创建列表 - 使用 java.lang.comparator 设计比较器并编写逻辑来对每个偶数元素进行排序

              【讨论】:

              • Arrays.asList(),不是Arrays.toList(),你不需要它,因为还有Arrays.sort()
              猜你喜欢
              • 2013-05-26
              • 2021-08-16
              • 2014-08-10
              • 2019-06-09
              • 1970-01-01
              • 2019-08-07
              • 2021-07-14
              • 2013-05-26
              相关资源
              最近更新 更多