[英]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());
然后,您将按照自己想要的方式对收藏列表进行排序。
我认为您想要一个可以定义为的类的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;
}
}
当然,你可以找到一个简单的方法通过实例比较提供颠倒的次序ASCENDING
或DESCENDING
顺序
与Comparator一起使用Collections.sort() 。
但是,您将丢失ID
信息,因为它是基于ArrayList的索引的。 因此,如果使用此方法并希望保留ID信息,则需要像execution
和cost
一样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.