简体   繁体   中英

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

I want to create a table like structure in Java as shown in the image

Table structure 在此处输入图片说明 Though I am not an expert in Java, I have tried to implement it using Arraylist structure as follows:

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);
}

Where the values of 'n', 'exectime[n]' and 'cost[n]' will be read from a file and 'n' is the total number of 'ids' that needs to be created.

After creating the table, I want to sort it based on the 'execution time' value and 'cost' value, both increasing and decreasing order. Please help me in this regards.

@snovelli's answer about using a class to encapsulate your data is a good point.

If you are using Java 8, you can easily create and chain comparators that use accessors.

For sorting a list of objects, it might look something like:

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

Sorting by execution time, followed by cost.

You could also use this to sort a List<List<Double>> if you really wanted to.

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

Sorting by element 0 of the list, followed by element 1.

Or for sorting in reverse order:

List<ExecutionTimeData> dataList = new ArrayList<>();
dataList.sort(Comparator
    .comparing(ExecutionTimeData::getExecutionTime).reversed()
    .thenComparing(ExecutionTimeData::getCost).reversed());
  • Use Collections as List < RegisterType > , RegisterType is created according to the type of registers present in the table (ex: with 3 double atributes)
  • Implement the Comparator interface Comparator< RegisterType >
  • Override the compare( RegisterType o1, RegisterType o2) method the way you want (define how to sort 2 elements of type RegisterType)
  • Inkove Collections.sort(List< RegisterType > list, ComparatorClass)

Then you will have your collection list sorted the way you want.

A table is a way to represent a list of objects, why not use a list of object then?

I think you want to have a SortedSet of a class that you could define as:

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 */      

}

Then you will simply have an unsorted list like

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

As pointed out from @VikrantKashyap to order the list with both value and cost you then must implement a Chained Comparator

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;
    }
}

And implement the comparators like this

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;
    }
}

And of course you can find out an easy way to invert the order by instantiating the comparators providing ASCENDING or DESCENDING order

Use Collections.sort() with Comparator .

However, you will loss your ID information because it is based on your index of the ArrayList. Therefore, if you use this method and want to keep you ID information, you need to add() ID to your ArrayList just like execution and cost .

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);

In above code, your dataList will sorted with cost , because it is at the index 1 of the ArrayList.

However, the better way (in readability) is you put your column into a Class, not just a ArrayList. For example, you can create a Class like this:

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;
    }
}

And implement static Comparator inside that class. It will improve the readability of your code.

I think You should use a Chained Comparator to implement sorting using multiple attributes. Because If you use a single Comparator Individually It will sort the data according to its own Compare() Method Implementation.

Better to Go with Chained Comparator which sort your data on multiple attribute ... Try the Following Link ==> Sorting a list by multiple attributes example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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