ellangog
ellangog

Reputation: 67

Sorting Arrays With Pairs of Numbers

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

Answers (3)

apcris
apcris

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

cyon
cyon

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

FThompson
FThompson

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

Related Questions