3

I got lot of sort example in single value inside pojo class.

but i want to sort with multiple value look like below example

before sort

Name          City           Roll
--------------------------------------

    sekhar ---------bbsr------------23
    himanshu -------agra------------23
    nitin ----------delhi------------23
    nitin ----------delhi------------22
    nitin ----------bbsr------------23
    arun -----------patna------------23
    arun -----------kendrapara-------23

after sort

Name          City           Roll
--------------------------------------

    arun -------kendrapara------------23
    arun -------patna------------23
    himanshu ----agra------------23
    nitin -------bbsr------------23
    nitin -------delhi------------22
    nitin -------delhi------------23
    sekhar -------bbsr------------23

My code is here

package example;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Demo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Demo demo = new Demo();
        List<Student> list = new ArrayList<Student>(); // your Car list
        Student st = demo.new Student();
        st.setName("sekhar");
        st.setCity("bbsr");
        st.setRoll(23);
        list.add(st);
        st = demo.new Student();
        st.setName("himanshu");
        st.setCity("agra");
        st.setRoll(23);
        list.add(st);
        st = demo.new Student();
        st.setName("nitin");
        st.setCity("delhi");
        st.setRoll(23);
        list.add(st);
        st = demo.new Student();
        st.setName("nitin");
        st.setCity("delhi");
        st.setRoll(22);
        list.add(st);
        st = demo.new Student();
        st.setName("nitin");
        st.setCity("bbsr");
        st.setRoll(23);
        list.add(st);
        st = demo.new Student();
        st.setName("arun");
        st.setCity("patna");
        st.setRoll(23);
        list.add(st);
        st = demo.new Student();
        st.setName("arun");
        st.setCity("kendrapara");
        st.setRoll(23);
        list.add(st);
        System.out.println("before sort");
        System.out.println("Name:" + "-------------------" + "City...........roll");
        for (Student st1 : list) {
            System.out.println(st1.getName() + " --------------" + st1.getCity() + "------------" + st1.getRoll());
        }

        Collections.sort(list, demo.new CarHorsePowerComparator());
        System.out.println("after sort");
        System.out.println("Name:" + "-------------------" + "City...............roll");
        for (Student st1 : list) {
            System.out.println(st1.getName() + " --------------" + st1.getCity() + "------------" + st1.getRoll());
        }
    }

    public class Student {

        String name;
        String city;
        int roll;

        public int getRoll() {
            return roll;
        }

        public void setRoll(int roll) {
            this.roll = roll;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    class CarHorsePowerComparator implements Comparator<Student> {
        public int compare(Student stu, Student stu1) {
            int sort = (stu.getName() + stu.getCity() + stu.getRoll()).compareTo((stu1.getName() + stu1.getCity() + stu1.getRoll()));
            return sort;
        }
    }
}

but i'am using custom comparator

class CarHorsePowerComparator implements Comparator<Student> {
            public int compare(Student stu, Student stu1) {
                int sort = (stu.getName() + stu.getCity() + stu.getRoll()).compareTo((stu1.getName() + stu1.getCity() + stu1.getRoll()));
                return sort;
            }

it's working for me but it's not right way. how to write this code in correct way Please suggest me.

int sort = (stu.getName() + stu.getCity() + stu.getRoll()).compareTo((stu1.getName() + stu1.getCity() + stu1.getRoll()));
4
  • Why is not the right way? I like the use of custom comparators. Commented Oct 18, 2013 at 9:21
  • @RamonBoza int sort = (stu.getName() + stu.getCity() + stu.getRoll()).compareTo((stu1.getName() + stu1.getCity() + stu1.getRoll())); this concat stu.getName() + stu.getCity() + stu.getRoll() look like not a correct way Commented Oct 18, 2013 at 9:22
  • Be more clear, with an expected result, of the kind of compare you need, because I can think in a lot of ways to compare Commented Oct 18, 2013 at 9:24
  • just like sql query sort with multiple field Commented Oct 18, 2013 at 9:26

3 Answers 3

3
(stu.getName() + stu.getCity() + stu.getRoll()).compareTo((stu1.getName() + stu1.getCity() + stu1.getRoll())) 

means you are contcatinating Name, City and Roll number and sorting on the resulting string.

You should decide the sorting priorities first and sort on the fields in that order. Looking at the expected result seems like you want to sort on name first then on city and lastly on roll.

class CarHorsePowerComparator implements Comparator<Student> {
            public int compare(Student stu, Student stu1) {
                int sort;
                // Sort on Name first 
                sort = stu.getName().compareTo(stu1.getName);
                if(sort == 0){
                  // If name is equal, sort on city
                  sort = stu.getCity().compareTo(stu1.getCity);
                }   
                if(sort == 0){
                  // If name and city is equal, sort on Roll
                  sort = Integer.compare(stu.getRoll(),stu1.getRoll());
                } 
                return sort;
            }
}
Sign up to request clarification or add additional context in comments.

5 Comments

@Himanshu: Can you add something more? Not able to understand the probelm
please one thing more. how to descending order this list
@Himanshu: Just compare stu1 with stu like stu1.getName().compareTo(stu.getName); instead of stu.getName().compareTo(stu1.getName);
You can not use compareTo on getRoll().
@Vash: Didnt noticed that its int, updated my answer. Thanks!
0
int sort = stu.getName().compareTo(stu1.getName());
if (sort == 0)
    sort = stu.getCity().compareTo(stu1.getCity())
if (sort == 0)
...
return res;

The point is that you continue comparison only if current components are equal

Comments

0

When you are using the plus operator you create lots of new String objects. String should be used to store some data not for logic purpose.

You should not use the parameters names as stu and stu1, because is error prone. You can use me and other or left and 'right'.

You do not need a class declaration as you will be reusing it. The annonymous is fine

private final static Comparator<Student> STUDENT_NAME_CITY_ROLL_COMPARATOR = new Comparator<Student> {

  private final Collator collator = Collator.getInstance(); //Default local is taken. 

  public int compare(Student left, Student right) {

    int result = collator.compare(left.getName(),right.getName()); 

    if(result == 0) {
        result = collator.compare(left.getCity(),right.getCity());
    } 

    if(result == 0) {
        result = Integer.compare(left.getRoll(), right.getRoll()); //JDK 7
       //result = Double.compare(left.getRoll(), right.getRoll());
    }

    return result;
}

Note: That the implementation will throw an NPE when some of the elements are null.

Collator

Integer.compare(int,int)

4 Comments

yes it's working. can you provide any generic idea when we are pass a list Collections.sort(list, demo.new CarHorsePowerComparator()); then automatic detect projo then compare automatic their data.
@Himanshu, If you replace the automatic, with logic that you will place in some method then you will have the answer. Now I can not tell you as I did not understand your requirements.
I want this code int result = collator.compare(left.getName(),right.getName()); if(result == 0) { result = collator.compare(left.getCity(),right.getCity()); } if(result == 0) { result = Integer.compare(left.getRoll(), right.getRoll()); //JDK 7 //result = Double.compare(left.getRoll(), right.getRoll()); } now manually check but i want when pass generic then automatic check this condition according their field
@Himanshu, I do not get what you request is. What to do mean by generic and automatic and condition. A use case might help...

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.