2

I have this class:

public class Test {

  private int    priority;
  private String desciption;
...
}

and I have this arraylist:

Priority: 1, Description: C2
Priority: 2, Description: C1
Priority: 3, Description: C1
Priority: 4, Description: C2

I want this result:

Priority: 1, Description: C2
Priority: 4, Description: C2
Priority: 2, Description: C1
Priority: 3, Description: C1

How I have to do this with comparator? Thank you!

EDIT:

I reply to all of your questions:

@retro: no. description is a string without a specific format. it can be empty, too.

@tobias_k: first "group" by description and than order by priority. priority is always not equals.

@user270349:

this is my try:

int result = 0;
if (o1.getPriority() < o2.getPriority()) result = -1;
else if (o1.getPriority() > o2.getPriority()) result = 1

result *= o1.getDescription().compareTo(o2.getDescription());

return result;

EDIT 2:

another input/output example:

and I have this arraylist:

Priority: 1, Description: C2
Priority: 2, Description: C3
Priority: 3, Description: C1
Priority: 4, Description: C2

I want this result:

Priority: 1, Description: C2
Priority: 4, Description: C2
Priority: 2, Description: C3
Priority: 3, Description: C1

THIS IS MY SOLUTION:

            List<Test> testList = new ArrayList<>();
    testList.add(new Test(4, "C2"));
    testList.add(new Test(2, "C3"));
    testList.add(new Test(3, "C1"));
    testList.add(new Test(1, "C2"));


    Comparator<Test> comparator = new Comparator<Test>() {

        @Override
        public int compare(Test o1, Test o2) {
            int res = o1.getDescription().compareTo(o2.getDescription());
            if (res == 0)
                return o1.getPriority() < o2.getPriority() ? -1 : 1;
            else
                return res;
        }
    };

    Collections.sort(testList, comparator);


    List<String> valoriInseriti = new ArrayList<>();
    List<Test> grouping = new ArrayList<>();
    for (Test t : testList) {
        if (!valoriInseriti.contains(t.getDescription())) {
            valoriInseriti.add(t.getDescription());
            grouping.add(t);
        }
    }


    comparator = new Comparator<Test>() {

        @Override
        public int compare(Test o1, Test o2) {
            return o1.getPriority() < o2.getPriority() ? -1 : 1;
        }
    };

    Collections.sort(grouping, comparator);


    Collections.sort(testList, comparator);

    List<Test> output = new ArrayList<>();
    for (Test t1 : grouping) {
        for (Test t2 : testList) {
            if (t2.getDescription().equals(t1.getDescription())) {
                output.add(t2);
            }
        }
    }

    System.out.println("==============================");
    for (Test t : output)
        System.out.println(t);
7
  • 1
    Do the descriptions always have the same format? Always one char, one digit? Can there be other chars, more digits? Commented Dec 5, 2013 at 12:11
  • 1
    Please describe how you want the comparator to work: Primarily by description, descending, and secondarily by priority, ascending? Also, what have you tried, and what's the problem? Commented Dec 5, 2013 at 12:12
  • What did you try? What don't you understand about Comparator interface in the javadoc? What is the requirement (in English, not just an example). -1 Commented Dec 5, 2013 at 12:21
  • I think your code is right but don't match the requirements. I think, IMHO, that you didn't understand the requirements. Maybe you need to group by description and sort the groups by the highest priority in the group and then sort within the group by priority too? I wouldn't do that just sorting with a comparator. I would represent as objects the groups themselves. Commented Dec 5, 2013 at 13:03
  • @user270349: I understand the problem and the question is if I can solve this problem with only comparator or not :) Commented Dec 5, 2013 at 13:15

6 Answers 6

4

Test implements Comparator and override compare() method

  public class Test implements Comparator<Test>{
    private int    priority;
    private String desciption;

    @Override
    public int compare(Test o1, Test o2) {
       // your code here
    }

  }
Sign up to request clarification or add additional context in comments.

Comments

1
Comparator<Test> myComparator = new Comparator<Test>() {
    public int compare(Test o1, Test o2) {
        int result = o2.desciption.compareTo(o1.desciption);

        if (result == 0) {
            return o1.priority - o2.priority;
        }

        return result;

    }
};

List<Test> sortedList = Collections.sort(testList, myComparator);

1 Comment

this example work with example, but if i have this input Priority: 1, Description: C2 Priority: 2, Description: C3 Priority: 3, Description: C1 Priority: 4, Description: C2 the output should be Priority: 1, Description: C2 Priority: 4, Description: C2 Priority: 2, Description: C3 and your example doesn't work. thank you anyway!
0
Comparator<Test> comparator = new Comparator<Test>() {

            @Override
            public int compare(Test o1, Test o2) {
                return o1.desciption.compareTo(o2.desciption);
            }
                  };

As, your problem specifies, you want to order the object of Test class in descending order with respect to description field, use Collections.reverseOrder(comparator)

Comparator<Test>reverse = Collections.reverseOrder(comparator);

Comments

0

First thing you want to do is make your Test class implement Comparator.

public class Test implements Comparator<Test> {
    // Fields etc.

    public int compare(Test test1, Test test2)
    {
         // Add your logic in here.
         return test1.getDescription().compareTo(test2.getDescription()) * -1;
    }
}

This will work because String compares lexographically. It will attempt to sort in ascending order, in terms of the first letter. If the first letter is equal, it will move onto the next value. By reversing it, you can store in descending order.

Then you sort it, use Collections.sort(myList);. And here is a working ideone example: http://ideone.com/SdFGFg

4 Comments

Shouldn't it rather implement Comparable?
Shouldn't it rather implement Only if this comparison is the logical way to compare then, quite/most often the required order of comparison is required it in a different component and there may well be different sorting requirements.
Agreed that Comparable should only be used for the one natural comparison (if any), and any "funny" comparisons should be done with Comparator. But then IMHO the Comparator should be a separate class, and not the class of the object to be compared.
I think, in terms of good design, the Comparator should be a completely different class rather than an anonymous object, but I do think that for the context of the question, this answer would suffice.
0

Do like this

Your TestComparator

class TestComparator implements Comparator<Test> {
    @Override
    public int compare(Test o1, Test o2) {

        String[] arr1 = o1.getDesciption().split("(?<=\\D)(?=\\d)");
        String[] arr2 = o2.getDesciption().split("(?<=\\D)(?=\\d)");
        if(Integer.parseInt(arr2[1])!=Integer.parseInt(arr1[1])){
            return  new Integer(Integer.parseInt(arr2[1])).compareTo(Integer.parseInt(arr1[1]));
        }
        if(o1.getPriority()!=o2.getPriority()){
           return   new Integer(o1.getPriority()).compareTo(o2.getPriority());
        }
        return 0;
    }    
}

your sorting

 System.out.println(list);      
 Collections.sort(list,new TestComparator());
 System.out.println("After sorting");
 System.out.println(list);

your output

[Test [priority=1, desciption=C2], Test [priority=2, desciption=C1], Test [priority=3, desciption=C1], Test [priority=4, desciption=C2]]
After sorting
[Test [priority=1, desciption=C2], Test [priority=4, desciption=C2], Test [priority=2, desciption=C1], Test [priority=3, desciption=C1]]

2 Comments

this example work with example, but if i have this input Priority: 1, Description: C2 Priority: 2, Description: C3 Priority: 3, Description: C1 Priority: 4, Description: C2 the output should be Priority: 1, Description: C2 Priority: 4, Description: C2 Priority: 2, Description: C3 and your example doesn't work. thank you anyway!
@FabioMignogna Please update your question with your input and expected answer.
0

I think you should sort (with comparator), then group, then sort the groups (with another comparator that may use the first comparator applied to the first element on the list), then degroup.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.