Android-java - Как отсортировать список объектов по определенному значению внутри объекта


112

Я пытаюсь отсортировать массив объектов по определенному значению внутри объекта. Как лучше всего сделать это? Должен ли я использовать Collections.sort () с каким-то компаратором?

Я пытаюсь отсортировать список объектов по значению с плавающей запятой, которое они содержат в одной из переменных.

РЕДАКТИРОВАТЬ: Это то, что у меня есть:

public class CustomComparator implements Comparator<Marker> {
    @Override
    public int compare(Mark o1, Mark o2) {
        return o1.getDistance().compareTo(o2.getDistance());
    }
}

сообщение об ошибке: Невозможно вызвать compareTo (double) для примитивного типа double.

Это потому, что компаратор не может вернуть ничего, кроме определенного типа?


2
«Должен ли я использовать Collections.sort () с каким-нибудь компаратором?» Да, звучит как хорошая идея
Кеннет

Я не знаю, имеет ли это значение, но количество объектов в списке будет достигать 80. Вот почему я немного запутался в использовании компаратора, если это так, потому что он сравнивает только два значения одновременно.
Джеймс Андресакис

Вот как работает сортировка. Сначала добавьте один элемент в список. При добавлении next; должно ли это идти до или после текущего в списке. При добавлении третьего элемента сравнить с первым элементом в списке, если после, сравнить со следующим элементом. И так далее.
Кеннет

Ответы:


98

Вы должны использовать Comparable вместо Comparator, если сортировка по умолчанию - это то, что вы ищете.

Смотрите здесь, это может помочь - когда класс должен быть Comparable и / или Comparator?

Попробуй это -

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

public class TestSort {

    public static void main(String args[]){

        ToSort toSort1 = new ToSort(new Float(3), "3");
        ToSort toSort2 = new ToSort(new Float(6), "6");
        ToSort toSort3 = new ToSort(new Float(9), "9");
        ToSort toSort4 = new ToSort(new Float(1), "1");
        ToSort toSort5 = new ToSort(new Float(5), "5");
        ToSort toSort6 = new ToSort(new Float(0), "0");
        ToSort toSort7 = new ToSort(new Float(3), "3");
        ToSort toSort8 = new ToSort(new Float(-3), "-3");

        List<ToSort> sortList = new ArrayList<ToSort>();
        sortList.add(toSort1);
        sortList.add(toSort2);
        sortList.add(toSort3);
        sortList.add(toSort4);
        sortList.add(toSort5);
        sortList.add(toSort6);
        sortList.add(toSort7);
        sortList.add(toSort8);

        Collections.sort(sortList);

        for(ToSort toSort : sortList){
            System.out.println(toSort.toString());
        }
    }

}

public class ToSort implements Comparable<ToSort> {

    private Float val;
    private String id;

    public ToSort(Float val, String id){
        this.val = val;
        this.id = id;
    }

    @Override
    public int compareTo(ToSort f) {

        if (val.floatValue() > f.val.floatValue()) {
            return 1;
        }
        else if (val.floatValue() <  f.val.floatValue()) {
            return -1;
        }
        else {
            return 0;
        }

    }

    @Override
    public String toString(){
        return this.id;
    }
}

Привет, спасибо за ссылку :) Я перехожу с одного языка на другой, поэтому я всегда что-то
упускаю

366

Следуйте этому коду, чтобы отсортировать любой ArrayList

Collections.sort(myList, new Comparator<EmployeeClass>(){
    public int compare(EmployeeClass obj1, EmployeeClass obj2) {
        // ## Ascending order
        return obj1.firstName.compareToIgnoreCase(obj2.firstName); // To compare string values
        // return Integer.valueOf(obj1.empId).compareTo(Integer.valueOf(obj2.empId)); // To compare integer values

        // ## Descending order
        // return obj2.firstName.compareToIgnoreCase(obj1.firstName); // To compare string values
        // return Integer.valueOf(obj2.empId).compareTo(Integer.valueOf(obj1.empId)); // To compare integer values
        }
    });

17
Это должен быть главный ответ!
Джон Смит

3
простой и отличный ответ, слава братану :)
Садашив

1
Простой и маленький .. Спасибо!
Встречайте Vora

1
Это кажется действительно чистым. Спасибо. И еще один плюс за предоставленные советы.
Anurag


42

Я думаю это поможет тебе лучше

Person p = new Person("Bruce", "Willis");
Person p1  = new Person("Tom", "Hanks");
Person p2 = new Person("Nicolas", "Cage");
Person p3 = new Person("John", "Travolta");

ArrayList<Person> list = new ArrayList<Person>();
list.add(p);
list.add(p1);
list.add(p2);
list.add(p3);

Collections.sort(list, new Comparator() {
    @Override
    public int compare(Object o1, Object o2) {
        Person p1 = (Person) o1;
        Person p2 = (Person) o2;
        return p1.getFirstName().compareToIgnoreCase(p2.getFirstName());
    }
});

24

Теперь не нужно заниматься боксом (т.е. не нужно создавать OBJECT с использованием нового оператора, используйте valueOf, установленное с compareTo of Collections.Sort ..)

1) По возрастанию

Collections.sort(temp, new Comparator<XYZBean>() 
{
     @Override
     public int compare(XYZBean lhs, XYZBean rhs) {

       return Integer.valueOf(lhs.getDistance()).compareTo(rhs.getDistance());
      }
 });

1) По убыванию

Collections.sort(temp, new Comparator<XYZBean>() 
{
     @Override
     public int compare(XYZBean lhs, XYZBean rhs) {

       return Integer.valueOf(rhs.getDistance()).compareTo(lhs.getDistance());
      }
 });

2

«Android-java» никоим образом не отличается от «нормальной java», так что да, Collections.sort()было бы неплохо.


1
Но как мне отсортировать его по значению внутри объекта. Вот на чем я застрял.
Джеймс Андресакис

2
public class DateComparator implements Comparator<Marker> {
    @Override
    public int compare(Mark lhs, Mark rhs) {
        Double distance = Double.valueOf(lhs.getDistance());
        Double distance1 = Double.valueOf(rhs.getDistance());
        if (distance.compareTo(distance1) < 0) {
            return -1;
        } else if (distance.compareTo(distance1) > 0) {
            return 1;
        } else {
            return 0;
        }
    }
}

ArrayList(Marker) arraylist;

Как пользоваться:

Collections.sort(arraylist, new DateComparator());

2

Вы можете сравнить две строки, используя this.

Collections.sort(contactsList, new Comparator<ContactsData>() {

                    @Override
                    public int compare(ContactsData lhs, ContactsData rhs) {

                        char l = Character.toUpperCase(lhs.name.charAt(0));

                        if (l < 'A' || l > 'Z')

                            l += 'Z';

                        char r = Character.toUpperCase(rhs.name.charAt(0));

                        if (r < 'A' || r > 'Z')

                            r += 'Z';

                        String s1 = l + lhs.name.substring(1);

                        String s2 = r + rhs.name.substring(1);

                        return s1.compareTo(s2);

                    }

                });

А теперь создайте класс ContactData.

public class ContactsData {

public String name;
public String id;
public String email;
public String avatar; 
public String connection_type;
public String thumb;
public String small;
public String first_name;
public String last_name;
public String no_of_user;
public int grpIndex;

public ContactsData(String name, String id, String email, String avatar, String connection_type)
{
    this.name = name;
    this.id = id;
    this.email = email;
    this.avatar = avatar;
    this.connection_type = connection_type;

}
}

Вот список контактов:

public static ArrayList<ContactsData> contactsList = new ArrayList<ContactsData>();

1

Либо создайте объект, Comparatorкоторый может сравнивать ваши объекты, либо, если все они являются экземплярами одного и того же класса, вы можете реализовать этот класс Comparable. Затем вы можете использовать Collections.sort () для фактической сортировки.


Я пошел дальше и реализовал Comparable в своем классе, но создал метод для вызова sort в списке, когда мне нужно его отсортировать, но как мне отсортировать его по значению в объекте?
Джеймс Андресакис

compareTo()-Метод , где вы делаете сравнение. Немного прибегая к помощи дал несколько подробных примеров о том , как использовать его, вот один из них: javadeveloper.co.in/java-example/java-comparable-example.html
Jave

Я установил метод, аналогичный приведенному в примере, однако получаю сообщение об ошибке, в котором говорится, что я не могу использовать compareTo для двойного приведения. Кажется, по какой-то причине то, что я делаю, не нравится. Невозможно вызвать compareTo (double) для примитивного типа double. Я добавлю свой код вверху, чтобы показать, что я имею в виду
Джеймс андресакис

1

Класс модели:

public class ToDoModel implements Comparable<ToDoModel> {
    private String id;
    private Date taskDate;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getTaskDate() {
        return taskDate;
    }

    public void setTaskDate(Date taskDate) {
        this.taskDate = taskDate;
    }

    @Override
    public int compareTo(ToDoModel another) {
        return getTaskDate().compareTo(another.getTaskDate());  
    }
}

Теперь установите данные в ArrayList

for (int i = 0; i < your_array_length; i++) {
    ToDoModel tm = new ToDoModel();
    tm.setId(your_id);
    tm.setTaskDate(your_date);
    mArrayList.add(tm);
}

Теперь отсортировать ArrayList

Collections.sort(toDoList);

Резюме: он будет сортировать ваши данные по дате


1

Для Kotlin вы можете использовать эту функцию

fun sortList(list: List<YourCustomPOJOClass?>) {

    //descending
    Collections.sort(
        list
    ) { o1, o2 -> Integer.valueOf(o1!!.intValueXYZ!!).compareTo(o2!!.intValueXYZ!!) }

//    //ascending
//    Collections.sort(
//        list
//    ) { o1, o2 -> Integer.valueOf(o2!!.intValueXYZ!!).compareTo(o1!!.intValueXYZ!!) }
}

и просто вызовите ее в activityили fragmentна

sortList(list)

0

У меня есть список, который показывает информацию обо всех клиентах, имена которых я сортирую, используя этот настраиваемый класс компаратора. У них есть дополнительные лерреты, кроме английских букв, которыми я управляю с помощью этого setStrength (Collator.SECONDARY)

 public class CustomNameComparator implements Comparator<ClientInfo> {
        @Override

    public int compare(ClientInfo o1, ClientInfo o2) { 

        Locale locale=Locale.getDefault();
        Collator collator = Collator.getInstance(locale);
        collator.setStrength(Collator.SECONDARY);
        return collator.compare(o1.title, o2.title);

    }
}


PRIMARY strength: Typically, this is used to denote differences between base characters (for example, "a" < "b"). It is the strongest difference. For example, dictionaries are divided into different sections by base character. 
SECONDARY strength: Accents in the characters are considered secondary differences (for example, "as" < "às" < "at"). Other differences between letters can also be considered secondary differences, depending on the language. A secondary difference is ignored when there is a primary difference anywhere in the strings. 
TERTIARY strength: Upper and lower case differences in characters are distinguished at tertiary strength (for example, "ao" < "Ao" < "aò"). In addition, a variant of a letter differs from the base form on the tertiary strength (such as "A" and "Ⓐ"). Another example is the difference between large and small Kana. A tertiary difference is ignored when there is a primary or secondary difference anywhere in the strings. 
IDENTICAL strength: When all other strengths are equal, the IDENTICAL strength is used as a tiebreaker. The Unicode code point values of the NFD form of each string are compared, just in case there is no difference. For example, Hebrew cantellation marks are only distinguished at this strength. This strength should be used sparingly, as only code point value differences between two strings are an extremely rare occurrence. Using this strength substantially decreases the performance for both comparison and collation key generation APIs. This strength also increases the size of the collation key. 

**Here is a another way to make a rule base sorting if u need it just sharing**

/*      String rules="< å,Å< ä,Ä< a,A< b,B< c,C< d,D< é< e,E< f,F< g,G< h,H< ï< i,I"+"< j,J< k,K< l,L< m,M< n,N< ö,Ö< o,O< p,P< q,Q< r,R"+"< s,S< t,T< ü< u,U< v,V< w,W< x,X< y,Y< z,Z";
        RuleBasedCollator rbc = null;
        try {
            rbc = new RuleBasedCollator(rules);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String myTitles[]={o1.title,o2.title};
        Collections.sort(Arrays.asList(myTitles), rbc);*/

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.