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

Java:如何对两个对应的数组进行排序?,java,arrays,Java,Arrays,我有两个阵列: 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…)对第一个数组的数字进行重新排序,但我也希望第二个数组的城市进行相应的移动,以便它们在排序前后具有相

我有两个阵列:

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

您可以使用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]});
}
现在,您可以按数据填写列表:

...   
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);
}
...
使用此方法,您可以在
CityPair
类中为
ArrayList cities
替换
String[]cities
。然后,它将能够为每个值添加两个以上的城市。

这里有一个(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);
int[]number={25,20,50};
字符串[]城市={“纽约”、“新泽西”、“底特律”、“亚特兰大”、“芝加哥”、“洛杉矶”};
Map Map=newtreemap(Comparator.comparing(Integer.class::cast,Integer::compare).reversed());
对于(迭代器n=Arrays.stream(numbers).Iterator(),
s=Arrays.stream(String.join(“,”,cities).split(“,(?=(([^,]*,){2})*[^,]*,[^,]*))))。迭代器();
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
,它有一个反向的
整数
比较器

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


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

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

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
没有带有自定义
比较器的
排序方法。我不知道为什么不


如果您想得到一个
列表
,那么使用
.collect(Collectors.toList())
而不是
toArray

,(与.NET不同,Java没有标准的库支持多数组排序)每个数组中的值是唯一的吗?您可能更喜欢使用Java中的映射来实现类似的功能。
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);
 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 + "]";
        }   
}
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]
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);