基于另一个数组的排序

时间:2018-11-22 16:53:32

标签: java arrays sorting

我有一个字符串数组列表totalValstotalVals中的每个条目都是一个字符串name和一个双loc,在将其插入数组列表之前,它们会被连接成一个字符串,例如:

totalVals.add(name + "," + loc);

这就是给我数据的方式。我将值分成一个字符串和一个双精度数组,如下所示:

String[] temp;
String[] names = new String[totalVals.size()];
double[] locs = new double[totalVals.size()];

for (int i = 0; i < totalVals.size(); I++){
    temp = totalVals.get(i).splot(",");
    names[i] = temp[0];
    locs[i] = Double.parseDouble(temp[1]);
}

但是,现在,我想对数据进行排序并将其放回数组列表中,然后再返回。我希望locs数据按降序排列,这可以通过使用Arrays.sort(locs, Collections.reverseOrder());来完成。但是我不知道如何对names进行排序,以使名称仍与它们原来所在的位置关联。

totalVals示例:{"Bahamas,32.2233","Zimbabwe,82.2443","India,56.2355","Australia,24.4363"}

将分为:

names = {"Bahamas","Zimbabwe","India","Australia"};
locs = {32.2233,82.2443,56.2355,24.4363};

然后将其排序为:

names = {"Zimbabwe","India","Bahamas","Australia"};
locs = {82.2443,56.2355,32.2233,24.4363};

那么我该如何对两个数组进行排序,以使两个数组中索引i的关联保持相同?

4 个答案:

答案 0 :(得分:3)

与其将您的数组转换为两个数组,不如将其转换为ArrayList<Pair>

Pair类如下:

public class Pair {
    private String country;
    private int loc;

    public Pair(String country, int loc) {
        this.country = country;
        this.loc = loc;
    }

    // getters and setters here
}

对数组进行排序:

Collections.sort(array, Comparator.comparingInt(Pair::getLoc));

然后将您的数组分成两个数组。

答案 1 :(得分:2)

与其将arraylist分成两个不同的数组并分别进行排序,不如将ArrayList基于double值按降序排序,然后将arraylist分为两个数组

 List<String> list = new ArrayList<>();
    list.add("Bahamas,32.2233");
    list.add("Zimbabwe,82.2443");
    list.add("India,56.2355");
    list.add("Australia,24.4363");

   List<String> result = list.stream().sorted((a,b)->b.substring(b.lastIndexOf(",")+1).compareTo(a.substring(a.lastIndexOf(",")+1))).collect(Collectors.toList());

 System.out.println(result);  //[Zimbabwe,82.2443, India,56.2355, Bahamas,32.2233, Australia,24.4363]

将列表分为double []数组和String []数组

double[] arr = result.stream().mapToDouble(i->Double.parseDouble(i.substring(i.lastIndexOf(",")+1))).toArray();
   System.out.println(Arrays.toString(arr)); // [82.2443, 56.2355, 32.2233, 24.4363]

String[] countries = result.stream().map(i->i.substring(0, i.lastIndexOf(","))).toArray(String[]::new);
   System.out.println(Arrays.toString(countries)); //[Zimbabwe, India, Bahamas, Australia]

在Java 8版本之前

通过将`Collections.sort()与自定义比较器一起使用,然后将列表分为两个不同的数组

 Collections.sort(list, new Comparator<String>() {

    @Override
    public int compare(String o1, String o2) {

        return o2.substring(o2.lastIndexOf(",")+1).compareTo(o1.substring(o1.lastIndexOf(",")+1));
    }
});
 System.out.println(list); //[Zimbabwe,82.2443, India,56.2355, Bahamas,32.2233, Australia,24.4363]

答案 2 :(得分:2)

TheWildHealer的解决方案简短而优雅。以下是针对较旧的Java平台的类似解决方案,以及用于测试的main()方法:

import java.util.ArrayList;
import java.util.Collections;

public class LocCountry implements Comparable {

    private double loc;
    private String country;

    public LocCountry(String country, double loc) {
        this.loc = loc;
        this.country= country;
    }

    public double getLoc() {return loc;}
    public String getCountry() {return country;}

    public String toString() { return country + " - " + loc;}
    public int compareTo(Object obj2) {
        double loc1 = this.getLoc();
        double loc2 = ((LocCountry)obj2).getLoc();

        if (loc1 > loc2) return 1;
        if (loc1 < loc2) return -1;
        return 0;
    }


    public static void main(String args[]) {
        ArrayList lcs = new ArrayList();

        lcs.add(new LocCountry("Bahamas"   , 82.2443));
        lcs.add(new LocCountry("Zimbabwe"  , 56.2355));
        lcs.add(new LocCountry("India"     , 32.2233));
        lcs.add(new LocCountry("Australia" , 24.4363));
        Collections.sort(lcs);
        Collections.reverse(lcs);

        for (int i = 0; i < lcs.size(); i++){
            System.out.println(lcs.get(i).toString());
        }
    }
}

结果:

Bahamas - 82.2443
Zimbabwe - 56.2355
India - 32.2233
Australia - 24.4363

答案 3 :(得分:2)

提供的方法TheWildHealer绝对比此方法更干净,但这是不需要自定义类的解决方案。流传输数组并将其映射到[String, Integer]的数组/对中。根据第二个值/整数排序,然后重构为字符串。

Arrays.stream(totalVals)
    .map(s -> s.split(","))
    .map(ss -> new Object[] {ss[0], Integer.parseInt(ss[1])})
    .sorted(Comparator.comparingInt(ss -> (Integer) ss[1]))
    .map(ss -> ss[0] + "," + ss[1])
    .toArray(String[]::new);