有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java:如何对两个对应的数组进行排序?

我有两个阵列:

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,两者中比较简单的一种)


共 (4) 个答案

  1. # 1 楼答案

    下面是一个(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循环中进行双重初始化。cities数组首先连接成一个字符串,然后拆分成pairs-as-a-string(使用适当的正则表达式)。两个迭代器的元素都填充了一个TreeMap,它有一个反向的Integer比较器

    由于TreeMaps排序的顺序迭代,因此keySet()values()流可用于生成结果数组

    for循环的结束条件检查两个迭代器是否有下一个元素可用,如果数组长度不相等,则会导致忽略较长数组中多余的元素

  2. # 2 楼答案

    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

  3. # 3 楼答案

    您可以使用树形图:

    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<Sting> cities。然后,它将能够增加超过两个城市的价值

  4. # 4 楼答案

    我尝试过这样的解决方案,它根据您的要求使用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]