Reputation: 67
Okay suppose I have an array of objects that look like this:
obj(from, to)
I want to to sort that array by comparing from and to. An example of what I want done:
Suppose I have objects with these parameters
(0,2) (2,4) (0,3) (4,5) (2,3)
I want the objects to be sorted in this order:
(0,2) (0,3) (2,3) (2,4) (4,5)
I want the first two "from" variables compared and the lower one placed in front. If they are equal then I want the second pair of number compared. To do this I created a compare method
public int compare (EdgeI e1, EdgeI e2) {
if(e1.from < e2.from) { return -1; }
else if(e1.from == e2.from) {
if(e1.to < e2.to) { return -1; }
else if(e1.to == e2.to) { return 0; }
else if(e1.to > e2.to) { return 1; }
}
return 1;
}
Would this work? And if so, how would I run this sort through the array? Thanks for any help.
EDIT
public class mySorter implements Comparator <EdgeI> {
public int compare(EdgeI e1, EdgeI e2) {
if(e1.from < e2.from) { return -1; }
else if(e1.from == e2.from) {
if(e1.to < e2.to) { return -1; }
else if(e1.to == e2.to) { return 0; }
else if(e1.to > e2.to) { return 1; }
}
return 1;
}
public void sorterM () {
Collections.sort(tet2, new mySorter());
}
}
I get the error Collections cannot be resolved, and tet2 cannot be resolved. Tet2 is a List delcared public in another class.
Upvotes: 3
Views: 2266
Reputation: 153
Late to the party but here is one possible implementation. You can avoid making the Comparators static by calling Collections.sort inside a method versus the main, which is realistically what you would do. Note that there are two Comparators. You're free to make as many as you want in the chance you want to have more than one way to sort, i.e., ascending versus descending in this case. It's just a matter of calling Collections.sort(edges, ORIGINAL);
or Collections.sort(edges, REVERSE);
.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class EdgeI{
private int from;
private int to;
public EdgeI(int f, int t)
{
from = f;
to = t;
}
public void setFromTo(int f, int t)
{
from = f;
to = t;
}
public int getFrom()
{
return from;
}
public int getTo()
{
return to;
}
public final static Comparator<EdgeI> REVERSE = new Comparator<EdgeI>()
{
@Override
public int compare(EdgeI e1, EdgeI e2)
{
if(e1.from < e2.from)
return 1;
if(e1.from > e2.from)
return -1;
//else they are equal
if(e1.to < e2.to)
return 1;
if(e1.to > e2.to)
return -1;
//else both edges are equal
return 0;
}
};
public final static Comparator<EdgeI> ORIGINAL = new Comparator<EdgeI>()
{
@Override
public int compare(EdgeI e1, EdgeI e2)
{
if(e1.from < e2.from) { return -1; }
else if(e1.from == e2.from)
{
if(e1.to < e2.to) { return -1; }
else if(e1.to == e2.to) { return 0; }
else if(e1.to > e2.to) { return 1; }
}
return 1;
}
};
public static void main(String[] args) {
ArrayList<EdgeI>edges = new ArrayList<EdgeI>(5);
edges.add(new EdgeI(0, 2));
edges.add(new EdgeI(2, 4));
edges.add(new EdgeI(0, 3));
edges.add(new EdgeI(4, 5));
edges.add(new EdgeI(2, 3));
System.out.println("\nBefore sorting:");
for(EdgeI i : edges)
System.out.println("("+i.getFrom()+", "+i.getTo()+")");
Collections.sort(edges, ORIGINAL);
System.out.println("\nAfter sorting:");
for(EdgeI i : edges)
System.out.println("("+i.getFrom()+", "+i.getTo()+")");
}
}
/*
Output on the console:
Before sorting:
(0, 2)
(2, 4)
(0, 3)
(4, 5)
(2, 3)
ORIGINAL:
After sorting:
(0, 2)
(0, 3)
(2, 3)
(2, 4)
(4, 5)
REVERSE:
After sorting:
(4, 5)
(2, 4)
(2, 3)
(0, 3)
(0, 2)
*/
Upvotes: 0
Reputation: 9538
What you can do is create a class which implements Comparator<Edge>
. You can then use your compare method to implement the method from the interface.
After you have done this you can use the comparator to sort a list of Edge
objects using Collections.sort()
.
This would look something like this:
import java.util.Collections;
import java.util.List;
import java.util.Comparator;
public class EdgeComparator implements Comparator<Edge> {
public int compare(Edge l, Edge r) { ... }
}
void yourCode() {
List<Edge> edges = ...;
Collections.sort(edges, new EdgeComparator());
//edges now contains the sorted edges
}
Here is the javadoc on Comparator and Collections.sort.
If you have an array instead of a list you can instead use Array.sort in the same way as Collections.sort
.
Upvotes: 2
Reputation: 28687
You can either make your EdgeI objects comparable, or you can create an individual comparator to handle comparing EdgeI objects. In this situation, (assuming you wrote the EdgeI class), the more object-oriented approach is to implement Comparable.
public class EdgeI implements Comparable<EdgeI> {
...
public int compareTo(EdgeI other) {
// implement your compare method to use this and other instead of e1 and e2
}
...
}
Then, you can use plain Arrays.sort
and the method will sort the edges based off of their natural ordering, which is specified by the inherited compareTo
method.
EdgeI[] edges = ...;
Arrays.sort(edges);
Alternatively, you can implement a Comparator and pass that to the sort method along with the target array to sort.
public class EdgeComparator implements Comparator<EdgeI> {
public int compare(EdgeI e1, EdgeI e2) {
// your method in its exact format
}
}
And then to sort it:
EdgeI[] edges = ...;
Arrays.sort(edges, new EdgeComparator());
Upvotes: 1