【问题标题】:Java: How to sort two corresponding arrays?Java:如何对两个对应的数组进行排序?
【发布时间】:2015-12-07 02:57:51
【问题描述】:

我有两个数组:

First array:
25, 20, 50, 30, 12, 11...

Second Array: 
New York, New Jersey, Detroit, Atlanta, Chicago, Los Angeles

第二个数组中的每两个城市对应第一个数组中的一个值。

示例:纽约和新泽西对应 25,底特律和亚特兰大对应 20,依此类推。

我想按降序(50、30、25、20...)对第一个数组的数字进行重新排序,但我也希望第二个数组的城市相应地移动,以便它们在之前和之前具有相同的值排序后。

我该如何完成这项任务? (我可以使用 ArrayList 或 Array,无论哪个更简单)

【问题讨论】:

标签: java arrays


【解决方案1】:

你可以使用 TreeMap:

Map<Integer, String[]> map = new TreeMap<>();
for(int i=0;i<firstArray.length;i++){
   map.put(firstArray[i], new String[]{secondArray[i * 2], secondArray[i*2+1]});
}

并且这张地图会按照关键的自然顺序进行排序。

但我建议你创建容器类。比如:

public class CityPair{
  public int value;
  public String[] cities = new String[2]; 
}

现在您可以按您的数据填写列表:

...   
ArrayList list = new ArrayList<CityPair>();

for(int i=0; i<firstArray.length; i++){
  CityPair pair = new CityPair();
  pair.value = firstArray[i];
  pair.cities[0] = secondArray[i*2];
  pair.cities[1] = secondArray[i*2+1];
  list.add(pair);
}
...

如您所见,我没有检查“索引越界”的索引,但您应该这样做。之后,您可以对列表进行排序。您可以使用例如Bubble sort 算法手动执行此操作,但更好的方法是编写自定义比较器:

public class CityPairComparator implements Comparator<CityPair> {
    @Override
    public int compare(CityPair pair1, CityPair pair2) {
        return Integer.compare(pair1.value, pair2.value);
    }
}

现在您可以使用 Collections 实用程序类对列表进行排序:

Collections.sort(list, new CityPairComparator());

使用此方法,您可以将CityPair 类中的String[] cities 替换为ArrayList&lt;Sting&gt; cities。然后每个值将能够添加两个以上的城市。

【讨论】:

    【解决方案2】:

    这是一个(4 行)解决方案,也可以处理不匹配的数组长度:

    int[] numbers = {25, 20, 50};
    String[] cities = {"New York", "New Jersey", "Detroit", "Atlanta", "Chicago", "Los Angeles"};
    
    Map<Object, Object> map = new TreeMap<>(Comparator.comparing(Integer.class::cast, Integer::compare).reversed());
    for (Iterator<?> n = Arrays.stream(numbers).iterator(),
        s = Arrays.stream(String.join(",", cities).split(",(?=(([^,]*,){2})*[^,]*,[^,]*$)")).iterator();
        n.hasNext() && s.hasNext(); )
        map.put(n.next(), s.next());
    numbers = map.keySet().stream().map(String::valueOf).mapToInt(Integer::parseInt).toArray();
    cities = map.values().stream().map(String::valueOf).map(s -> s.split(",")).flatMap(Arrays::stream).toArray(String[]::new);
    

    这会从每个数组的流中动态创建两个迭代器,都输入Object 以允许在 for 循环中进行双重初始化。城市数组首先加入一个字符串,然后拆分为字符串对(使用适当的正则表达式)。两个迭代器的元素都填充了一个 TreeMap,它有一个反向的 Integer 比较器。

    因为TreeMaps排序 顺序迭代,所以keySet()values() 的流可用于生成结果数组。

    for 循环的终止条件检查两个迭代器以查看是否有下一个元素可用,如果数组长度不相等,这会导致较长数组的多余元素被忽略。

    【讨论】:

      【解决方案3】:

      我尝试过这样的解决方案,它根据您的要求使用 Arraylist :

      首先,我为您的操作创建了一个新的数据结构。因为每个值将包含两个城市名称:

       public class Citizen implements Comparable<Citizen>  {
      
          private int citizenId;
          private String subjectOne;
          private String subjectTwo;
      
      
          public Citizen(int rollNumber, String subjectOne, String subjectTwo){
              this.citizenId = rollNumber;
              this.subjectOne = subjectOne;
              this.subjectTwo = subjectTwo;
          }
      
          public int getRollNumber() {
              return citizenId;
          }
          public void setRollNumber(int rollNumber) {
              this.citizenId = rollNumber;
          }
          public String getSubjectOne() {
              return subjectOne;
          }
          public void setSubjectOne(String subjectOne) {
              this.subjectOne = subjectOne;
          }
          public String getSubjectTwo() {
              return subjectTwo;
          }
          public void setSubjectTwo(String subjectTwo) {
              this.subjectTwo = subjectTwo;
          }
      
      
              public int compareTo(Citizen comparestu) {
                  int compareage=((Citizen)comparestu).getRollNumber();
                  /* For Ascending order*/
                  return this.citizenId-compareage;
      
                  /* For Descending order do like this */
                  //return compareage-this.studentage;
              }
      
              @Override
              public String toString() {
                  return "[ rollno=" + citizenId + ", subjectOne=" + subjectOne + ", subjectTwo=" + subjectTwo + "]";
              }   
      }
      

      正如您在此处看到的,用于比较的参数是使用 Comparable 接口实现的CitizenID。

      现在打电话:

      public static void main(String[] args) {
      
              ArrayList<Citizen> studentList = new ArrayList<Citizen>();
      
              studentList.add(new Citizen(25, "New York", "New Jersey"));
              studentList.add(new Citizen(20, "Detroit", "Atlanta"));
              studentList.add(new Citizen(50, "Chicago", "Los Angeles"));
              studentList.add(new Citizen(30, "Kolkata", "Delhi"));
              studentList.add(new Citizen(12, "Munmbai", "Baranasi"));
              studentList.add(new Citizen(11, "Bangalore", "Goa"));
      
      
      
              Collections.sort(studentList);
                 for(Citizen student: studentList){
                      System.out.println(student);
                 }
          }
      

      输出:

      [ rollno=11, subjectOne=Bangalore, subjectTwo=Goa]
      [ rollno=12, subjectOne=Munmbai, subjectTwo=Baranasi]
      [ rollno=20, subjectOne=Detroit, subjectTwo=Atlanta]
      [ rollno=25, subjectOne=New York, subjectTwo=New Jersey]
      [ rollno=30, subjectOne=Kolkata, subjectTwo=Delhi]
      [ rollno=50, subjectOne=Chicago, subjectTwo=Los Angeles]
      

      【讨论】:

        【解决方案4】:

        Java 8 提供了一种更优雅的方式来执行此操作,而无需单独的映射:

        int[] array1;
        String[] array2;
        
        array2 = IntStream.range(0, Math.min(array1, array2))
            .boxed().sorted(Comparator.comparingInt(i -> array1[i]))
            .map(i -> array2[i])
            .toArray(array2);
        

        只需要装箱是因为IntStream 没有带有自定义Comparatorsorted 方法。我不知道为什么不。

        如果您想以List 结尾,请使用.collect(Collectors.toList()) 而不是toArray

        【讨论】:

          猜你喜欢
          • 2011-04-23
          • 1970-01-01
          • 2016-03-12
          • 2019-06-07
          • 2014-07-22
          • 2016-07-26
          • 1970-01-01
          相关资源
          最近更新 更多