繁体   English   中英

在Java中对具有多个值的列表/数组列表/哈希图进行排序

[英]Sorting List of lists/ Arraylists/ Hashmaps with multiple values in Java

我想在Java中创建一个像表一样的结构,如图所示

表结构 在此处输入图片说明 尽管我不是Java方面的专家,但是我尝试使用Arraylist结构来实现它,如下所示:

List<List<Double>> dataList = new ArrayList<List<Double>>();
for(int x = 0; x < n; x++){
    List<Double> tempList = new ArrayList<Double>();
    dataList.add(tempList);
}

for(int y = 0; y < n; y++){
    double execution = exectime[y];
    double cost= cost[y];
    dataList.get(y).add(execution);
    dataList.get(y).add(cost);
}

for (int z=0;z<dataList.size();z++) {
    Double v1=dataList.get(z).get(0);
    Double v2=dataList.get(z).get(1);

    System.out.println("ID"+z +" Execution time:" + v1 + "cost: " + v2);
}

从文件中读取“ n”,“ exectime [n]”和“ cost [n]”的值,而“ n”是需要创建的“ id”的总数。

创建表后,我想基于“执行时间”值和“成本”值对表进行排序,包括升序和降序。 请在这方面帮助我。

@snovelli关于使用类封装数据的答案是很不错的。

如果您使用的是Java 8,则可以轻松创建并链接使用访问器的比较器。

为了对对象列表进行排序,它可能类似于:

List<ExecutionTimeData> dataList = new ArrayList<>();
dataList.sort(Comparator
    .comparing(ExecutionTimeData::getExecutionTime)
    .thenComparing(ExecutionTimeData::getCost));

按执行时间排序,然后按成本排序。

如果确实需要,也可以使用此方法对List<List<Double>>进行排序。

List<List<Double>> doubleListList = new ArrayList<>();
doubleListList.sort(Comparator
    .comparing((List<Double> l) -> l.get(0))
    .thenComparing(l -> l.get(1)));

按列表的元素0排序,然后按元素1排序。

或以相反的顺序排序:

List<ExecutionTimeData> dataList = new ArrayList<>();
dataList.sort(Comparator
    .comparing(ExecutionTimeData::getExecutionTime).reversed()
    .thenComparing(ExecutionTimeData::getCost).reversed());
  • 将Collections用作List <RegisterType>时,RegisterType是根据表中存在的寄存器类型创建的(例如:具有3个双属性)
  • 实现比较器接口Comparator <RegisterType>
  • 覆盖您想要的方法compare(RegisterType o1,RegisterType o2)方法(定义如何对RegisterType类型的2个元素进行排序)
  • Inkove Collections.sort(List <RegisterType> list,ComparatorClass)

然后,您将按照自己想要的方式对收藏列表进行排序。

表是表示对象列表的一种方法,那么为什么不使用对象列表呢?

我认为您想要一个可以定义为的类的SortedSet

public class ExecutionTimeData{

    private final long id;
    private final long executionTime;
    private final int cost;

    public ExecutionTimeData(long id, long executionTime, int cost){
         this.id = id;
         this.executionTime = executionTime;
         this.cost = cost;
    }        

    /* Getters */      

}

然后,您将简单地得到一个未排序的列表,例如

List<ExecutionTimeData> unsortedList = new ArrayList<>();

正如@VikrantKashyap指出的,要同时订购值和成本的列表,则必须实现一个链式比较器

public class ExecutionTimeDataChainedComparator implements Comparator<ExecutionTimeData> {

    private List<Comparator<ExecutionTimeData>> listComparators;

    @SafeVarargs
    public ExecutionTimeDataChainedComparator (Comparator<ExecutionTimeData>... comparators) {
        this.listComparators = Arrays.asList(comparators);
    }

    @Override
    public int compare(ExecutionTimeData etd1, ExecutionTimeData etd2) {
        for (Comparator<ExecutionTimeData> comparator : listComparators) {
            int result = comparator.compare(etd1, etd2);
            if (result != 0) {
                return result;
            }
        }
        return 0;
    }
}

并像这样实现比较器

public class ExecutionTimeDataCostComparator implements Comparator<ExecutionTimeData > {

    @Override
    public int compare(ExecutionTimeData a, ExecutionTimeData b) {
       return b.getCost() > a.getCost()?-1:1;
    }
}

public class ExecutionTimeDataExecutionComparator implements Comparator<ExecutionTimeData > {

    @Override
    public int compare(ExecutionTimeData a, ExecutionTimeData b) {
       return b.getExecutionTime() > a.getExecutionTime()?-1:1;
    }
}

当然,你可以找到一个简单的方法通过实例比较提供颠倒的次序ASCENDINGDESCENDING顺序

与Comparator一起使用Collections.sort()

但是,您将丢失ID信息,因为它是基于ArrayList的索引的。 因此,如果使用此方法并希望保留ID信息,则需要像executioncost一样add() ID add() ID到ArrayList中。

Comparator<List<Double>> ORDER = new Comparator<List<Double>>() {
    @Override
    public int compare(List<Double> lhs, List<Double> rhs) {
        if (lhs.get(1) < rhs.get(1)) return -1;
        if (lhs.get(1) == rhs.get(1)) return 0;
        return 1;
    }
};

Collections.sort(dataList, ORDER);

在上面的代码中,您的dataList将按cost排序,因为它在ArrayList的索引1处。

但是,更好的方法(在可读性上)是将列放入Class中,而不仅仅是ArrayList。 例如,您可以创建一个这样的类:

class Information {
    private int id;
    private double execution;
    private double cost;

    Information(int id, double execution, double cost) {
        this.id = id;
        this.execution = execution;
        this.cost = cost;
    }
}

并在该类中实现静态比较器。 它将提高代码的可读性。

我认为您应该使用链式Comparator来实现使用多个属性的sorting 因为如果单独使用一个Comparator ,它将根据其自己的Compare()方法实现对数据进行排序。

最好与Chained Comparator ,后者可对多个属性的数据进行排序...尝试以下链接==> 按多个属性对列表进行排序的示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM