Natalie B
Natalie B

Reputation: 33

How to implement a Chain Comparator

I am creating the program that sorts an ArrayList of objects with parameters:

String name
int types(1-3)
int diffs(stands for difficulty, 1-3))
and in days(days until deadline).

I want to sort the list of objects using all parameters at sequentially in that order. I'm just getting used to comparators and was wondering how exactly I would implement a comparator chain in my code. I know there are other methods of doing this such as using if else statements inside one comparator or using compareToBuilder but I'm not sure which is best yet or if there are any other alternative methods I should consider.

Code for main:

import java.io.*;
import java.util.*;

public class InputItem
{
  public int row;
  public static void main(String args[])
  {

    String again;
    String names[] = new String[100];
    int types[] = new int[100];
    int diffs[] = new int[100];
    int days[] = new int[100];
    int row=0;
    do{
    System.out.println("Please input assignment name:");
    Scanner newNames = new Scanner(System.in);
    String name = newNames.nextLine();
    names[row] =name;

    System.out.println("Please input assignment type:");
    Scanner typeI = new Scanner(System.in);
    int type = typeI.nextInt();
    types[row] = type;

    System.out.println("Please input assignment difficulty:");
    Scanner diffI = new Scanner(System.in);
    int diff = diffI.nextInt();
    diffs[row] = diff;
   // input days...
    System.out.println("Would you like to add another item? Enter 'Yes' or 'No'");
    Scanner input = new Scanner(System.in);
      again = input.next();
      row++;
    }
    while(again.equalsIgnoreCase("Yes"));
    List<Itemss> WORK = new ArrayList<Itemss>();
    for(int count = 0; count<row; count++)
    {
      WORK.add(new Itemss(((types[count])), (names[count])));
    }
    Collections.sort(WORK, new COMP());

    System.out.println("Sorted List Entries: ");
    for(Itemss a: WORK)
    {
      System.out.println(a);
    }
  }
}

Code for Itemss class and comparator

import java.util.*;
class COMP implements Comparator<Itemss>
{
  @Override  //overides compareTo() method 
  public int compare(Itemss a1, Itemss a2)
  {
    if((a1).getType()< (a2).getType())
    {
        return 1;
    } 
    else
    {
      return -1;
    }
  }
}
public class Itemss
{
  private String name;
  private int type;
  //private int diff;  
  //private int days;

  public Itemss(int t, String n)
  {
    name = n;
    type = t;
    //diff = df;
    //days = da;
  }
  public String getName()
  {
    return name;
  }
  public void setName(String name)
  {
    this.name = name;
  }
  public int getType()
  {
    return type;
  }
  public void setType(int type)
 {
   this.type = type;
  }
  public String toString()
 {   
    return this.name + "-->Type:" + this.type ;
  }
}

Upvotes: 2

Views: 3950

Answers (2)

stakahop
stakahop

Reputation: 951

You should use something like this:

public void order(List<MyObject> myList) {

    Comparator<MyObject> byName = new Comparator<MyObject>() {
        @Override
        public int compare(MyObject o1, MyObject o2) {
            if (o1.getName() != null && o2.getName() != null) {
                return o1.getName().compareToIgnoreCase(o2.getName());
            }
            return -1;
        }
    };

    Comparator<MyObject> byType = new Comparator<MyObject>() {
        @Override
        public int compare(MyObject o1, MyObject o2) {
            if (o1.getType() != null && o2.getType() != null) {
                return o1.getType().compareTo(o2.getType());
            }
            return -1;
        }
    };

    Comparator<MyObject> byDiffs = new Comparator<MyObject>() {
        @Override
        public int compare(MyObject o1, MyObject o2) {
            if (o1.getDiffs() != null && o2.getDiffs() != null) {
                return o1.getDiffs().compareTo(o2.getDiffs());
            }
            return -1;
        }
    };

    Comparator<MyObject> byDays = new Comparator<MyObject>() {
        @Override
        public int compare(MyObject o1, MyObject o2) {
            if (o1.getDays() != null && o2.getDays() != null) {
                return o1.getDays().compareTo(o2.getDays());
            }
            return -1;
        }
    };

    ComparatorChain chain = new ComparatorChain();
    chain.addComparator(byName);
    chain.addComparator(byType);
    chain.addComparator(byDiffs);
    chain.addComparator(byDays);

    Collections.sort(myList, chain);

}

Upvotes: 0

Ian Mc
Ian Mc

Reputation: 5829

To follow is a basic approach. Your previous Comparator was strictly comparing greater than or less than. To chain, compare the next set of variables when current variables are equal. Here is an example:

class COMP implements Comparator<Items> {
    @Override // overides compareTo() method
    public int compare(Items a1, Items a2) {
        if (a1.getType() < a2.getType()) {
            return 1;
        } else if (a1.getType() > a2.getType()) {
            return -1;
        } else if (a1.getDiff() < a2.getDiff()) {
            return 1;
        } else if (a1.getDiff() > a2.getDiff()) {
            return -1;
        } else if (a1.getDays() < a2.getDays()) {
            return 1;
        } else if (a1.getDays() > a2.getDays()) {
            return -1;
        }
        return 0;
    }
}

Which creates a sample output like:

-- AFTER SORT --
Items [name=Item 8, type=3, diff=3, days=5]
Items [name=Item 9, type=3, diff=2, days=4]
Items [name=Item 7, type=3, diff=1, days=3]
Items [name=Item 4, type=2, diff=3, days=10]
Items [name=Item 5, type=2, diff=2, days=6]
Items [name=Item 6, type=2, diff=1, days=12]
Items [name=Item 3, type=1, diff=2, days=11]
Items [name=Item 1, type=1, diff=2, days=10]
Items [name=Item 2, type=1, diff=1, days=9]

Upvotes: 1

Related Questions