java - فرز ArrayList من الكائنات المخصصة حسب الممتلكات




sorting date comparator (21)

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;

public class test {

public static class Person {
    public String name;
    public int id;
    public Date hireDate;

    public Person(String iname, int iid, Date ihireDate) {
        name = iname;
        id = iid;
        hireDate = ihireDate;
    }

    public String toString() {
        return name + " " + id + " " + hireDate.toString();
    }

    // Comparator
    public static class CompId implements Comparator<Person> {
        @Override
        public int compare(Person arg0, Person arg1) {
            return arg0.id - arg1.id;
        }
    }

    public static class CompDate implements Comparator<Person> {
        private int mod = 1;
        public CompDate(boolean desc) {
            if (desc) mod =-1;
        }
        @Override
        public int compare(Person arg0, Person arg1) {
            return mod*arg0.hireDate.compareTo(arg1.hireDate);
        }
    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
    ArrayList<Person> people;
    people = new ArrayList<Person>();
    try {
        people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
        people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
        people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Collections.sort(people, new Person.CompId());
    System.out.println("BY ID");
    for (Person p : people) {
        System.out.println(p.toString());
    }

    Collections.sort(people, new Person.CompDate(false));
    System.out.println("BY Date asc");
    for (Person p : people) {
        System.out.println(p.toString());
    }
    Collections.sort(people, new Person.CompDate(true));
    System.out.println("BY Date desc");
    for (Person p : people) {
        System.out.println(p.toString());
    }

}

}

قرأت عن فرز ArrayLists باستخدام المقارنة ولكن في جميع الأمثلة التي استخدمها الناس مقارنة compareTo والتي وفقا لبعض البحوث هي طريقة لالسترات.

أردت فرز ArrayList لكائنات مخصصة بواسطة أحد خصائصها: كائن تاريخ ( getStartDay() ). عادة item1.getStartDate().before(item2.getStartDate()) خلال item1.getStartDate().before(item2.getStartDate()) لذلك كنت أتساءل عما إذا كان يمكنني كتابة شيء مثل:

public class CustomComparator {
    public boolean compare(Object object1, Object object2) {
        return object1.getStartDate().before(object2.getStartDate());
    }
}

public class RandomName {
    ...
    Collections.sort(Database.arrayList, new CustomComparator);
    ...
}

قد تكون مقتطفات التعليمات البرمجية هذه مفيدة. إذا كنت ترغب في فرز كائن في حالتي أريد الفرز حسب VolumeName:

public List<Volume> getSortedVolumes() throws SystemException {
    List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
    Collections.sort(volumes, new Comparator<Volume>() {
        public int compare(Volume o1, Volume o2) {
            Volume p1 = (Volume) o1;
            Volume p2 = (Volume) o2;
            return p1.getVolumeName().compareToIgnoreCase(
                    p2.getVolumeName());
        }
    });
    return volumes;
}

هذا يعمل. أنا استخدمها في jsp بي.


أفضل طريقة سهلة مع JAVA 8 هي لترتيب الأبجدية الإنجليزية

تطبيق الفصل

public class NewspaperClass implements Comparable<NewspaperClass>{
   public String name;

   @Override
   public int compareTo(NewspaperClass another) {
      return name.compareTo(another.name);
   }
}

فرز

  Collections.sort(Your List);

إذا كنت ترغب في الفرز الأبجدية التي تحتوي على أحرف غير الإنجليزية يمكنك استخدام الإعدادات المحلية ... تحت الرمز استخدام الفرز الطابع التركي ...

تطبيق الفصل

public class NewspaperClass implements Comparator<NewspaperClass> {
   public String name;
   public Boolean isUserNewspaper=false;
   private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));



   @Override
   public int compare(NewspaperClass lhs, NewspaperClass rhs) {
      trCollator.setStrength(Collator.PRIMARY);
      return trCollator.compare(lhs.name,rhs.name);
   }
}

فرز

Collections.sort(your array list,new NewspaperClass());

لجافا 8:

Collections.sort(list, comparing(ClassName::getName));

أو

Collections.sort(list, comparing(ClassName::getName).reversed());

يبدو أنه يعمل مع نوع تاريخ السلسلة أيضًا مثل "2015-12-14T21: 55: 51Z"

طريقة أخرى هي

Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));

Java 8 Lambda تقصر هذا النوع.

Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));

لقد وجدت معظم هذه الإجابات ، إن لم تكن كلها ، تعتمد على الفئة الأساسية (الكائن) لتنفيذها قابلة للمقارنة أو أن يكون لها واجهة مساعدة قابلة للمقارنة.

ليس مع حلّي! تتيح لك التعليمة البرمجية التالية مقارنة حقل الكائن من خلال معرفة اسم السلسلة الخاصة به. يمكنك بسهولة تعديله لعدم استخدام الاسم ، ولكنك تحتاج إلى فضحه أو إنشاء أحد الكائنات التي تريد مقارنتها.

Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));

public class ReflectiveComparator {
    public class FieldComparator implements Comparator<Object> {
        private String fieldName;

        public FieldComparator(String fieldName){
            this.fieldName = fieldName;
        }

        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public int compare(Object object1, Object object2) {
            try {
                Field field = object1.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);

                Comparable object1FieldValue = (Comparable) field.get(object1);
                Comparable object2FieldValue = (Comparable) field.get(object2);

                return object1FieldValue.compareTo(object2FieldValue);
            }catch (Exception e){}

            return 0;
        }
    }

    public class ListComparator implements Comparator<Object> {
        private String fieldName;

        public ListComparator(String fieldName) {
            this.fieldName = fieldName;
        }

        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public int compare(Object object1, Object object2) {
            try {
                Field field = object1.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                Comparable o1FieldValue = (Comparable) field.get(object1);
                Comparable o2FieldValue = (Comparable) field.get(object2);

                if (o1FieldValue == null){ return -1;}
                if (o2FieldValue == null){ return 1;}
                return o1FieldValue.compareTo(o2FieldValue);
            } catch (NoSuchFieldException e) {
                throw new IllegalStateException("Field doesn't exist", e);
            } catch (IllegalAccessException e) {
                throw new IllegalStateException("Field inaccessible", e);
            }
        }
    }
}

يجب أن تقوم فئة customComparator بتنفيذ java.util.Comparator لكي يتم استخدامها. يجب أن تضاف أيضا مقارنة () AND يساوي ()

مقارنة () يجب الإجابة على السؤال: هل الكائن 1 أقل من أو يساوي أو أكبر من الكائن 2؟

مستندات كاملة: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html


يمكنك فرز باستخدام جافا 8

yourList.sort(Comparator.comparing(Classname::getName));

or

yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));

نعم تستطيع. هناك خياران لمقارنة العناصر ، وواجهة Comparable ، وواجهة Comparator .

كل من هذه الواجهات تسمح لسلوك مختلف. يتيح لك المقارن جعل الكائن يتصرف وكأنك وصفت للتو سلاسل (في الواقع ، تنفذ سلسلة قابلة للمقارنة). الثاني ، المقارن ، يسمح لك بفعل ما تطلب القيام به. سوف تفعل ذلك على النحو التالي:

Collections.sort(myArrayList, new MyComparator());

سيؤدي ذلك إلى استخدام طريقة Collections.sort للمقارنة الخاصة بك آلية الفرز الخاصة بها. إذا كانت الكائنات الموجودة في ArrayList قابلة للتنفيذ ، يمكنك بدلاً من ذلك القيام بشيء كالتالي:

Collections.sort(myArrayList);

تحتوي فئة Collections على عدد من هذه الأدوات المفيدة والشائعة.


باستخدام Java 8 ، يمكنك استخدام مرجع أسلوب لمقارنك:

import static java.util.Comparator.comparing;

Collections.sort(list, comparing(MyObject::getStartDate));

نظرًا لأن التقنيات تظهر كل يوم ، ستتغير الإجابة في ذلك الوقت. ألقيت نظرة على LambdaJ ويبدو مثيرا للاهتمام.

يمكنك محاولة حل هذه المهام باستخدام LambdaJ . يمكنك العثور عليه هنا: http://code.google.com/p/lambdaj/

هنا لديك مثال على ذلك:

فرز تكراري

List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
        public int compare(Person p1, Person p2) {
           return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
        }
});

رتب مع امدا

List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

بالطبع ، وجود هذا النوع من الآثار الجمال في الأداء (بمعدل 2 مرات) ، ولكن يمكنك العثور على رمز أكثر قابلية للقراءة؟


من Java 8 وما بعده ، لا يتعين علينا استخدام Collections.sort() مباشرة. واجهة List لديها طريقة sort() الافتراضية:

List<User> users = Arrays.asList(user1,user2,user3);
users.sort( (u1, u2) -> { 
return u1.getFirstName.compareTo(u2.getFirstName());}); 

راجع http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html .


نعم ، هذا ممكن على سبيل المثال في هذه الإجابة أقوم بالفرز حسب الخاصية v للفئة IndexValue

    // Sorting by property v using a custom comparator.
    Arrays.sort( array, new Comparator<IndexValue>(){
        public int compare( IndexValue a, IndexValue b ){
            return a.v - b.v;
        }
    });

إذا لاحظت هنا فأنا أقوم بإنشاء فئة داخلية مجهولة (وهي Java للإغلاق) وتمريرها مباشرةً إلى طريقة sort من Arrays الفئة

قد يقوم Comparable أيضًا بتنفيذ Comparable (وهذا ما تفعله معظم المكتبات ومعظمها في جافا) ولكن ذلك من شأنه أن يحدد "ترتيب الفرز الطبيعي" للفصل الذاتي ، ولا يسمح لك بتوصيل المكونات الجديدة.


منذ Date تطبيق Comparable ، فإنه يحتوي على أسلوب compareTo تماماً مثل " String .

لذلك قد تبدو Comparator المخصصة لديك على Comparator :

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

يجب أن ترجع الطريقة compare() int ، حتى لا تتمكن من إرجاع قيمة boolean مباشرة كما لو كنت تخطط لها على أي حال.

سيكون كود التصنيف الخاص بك على غرار ما كتبته:

Collections.sort(Database.arrayList, new CustomComparator());

هناك طريقة أقصر قليلاً لكتابة كل هذا ، إذا لم تكن بحاجة إلى إعادة استخدام المقارنة ، فقم بكتابتها كفئة داخلية مضمنة:

Collections.sort(Database.arrayList, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
});

منذ java-8

يمكنك الآن كتابة المثال الأخير في نموذج أقصر باستخدام تعبير lambda Comparator :

Collections.sort(Database.arrayList, 
                        (o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

وتحتوي List على طريقة sort(Comparator) ، بحيث يمكنك تقصير ذلك إلى أبعد من ذلك:

Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

هذا هو عبارة شائعة مثل أن هناك طريقة مضمنة لإنشاء أداة Comparator للفئة باستخدام مفتاح قابل Comparable :

Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));

كل هذه هي أشكال مماثلة.


يمكن أن يؤدي استخدام استخدام Java 8 إلى تحديد أداة Comparator في سطر واحد باستخدام Comparator.comparing()

استخدم أي من الطرق التالية:

الخيار 1:

listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));

الخيار 2:

Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));

يمكنك استخدام Bean Comparator للفرز على أي خاصية في الفصل المخصص.


انا افضل هذه العملية:

public class SortUtil
{    
    public static <T> List<T> sort(List<T> list, String sortByProperty)
    {
            Collections.sort(list, new BeanComparator(sortByProperty));
            return list;
    }
}

List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");

إذا كانت قائمة الكائنات تحتوي على خاصية تسمى startDate ، فإنك تستخدم هذا startDate مرارًا وتكرارًا. يمكنك حتى سلسلة لهم startDate.time .

يتطلب ذلك أن يكون الكائن الخاص بك قابلاً Comparable مما يعني أنك تحتاج إلى إجراء Comparable compareTo و equals و hashCode .

نعم ، يمكن أن يكون أسرع ... ولكن الآن ليس عليك عمل مقارنة جديدة لكل نوع من أنواع الفرز. إذا كان بإمكانك توفير وقت التطوير والتخلي عن وقت التشغيل ، فقد تذهب مع هذا.


يمكنك تجربة Ordering الجوافة:

Function<Item, Date> getStartDate = new Function<Item, Date>() {
    public Date apply(Item item) {
        return item.getStartDate();
    }
};

List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
                          sortedCopy(items);

تعبير JAVA 8 lambda

Collections.sort(studList, (Student s1, Student s2) ->{
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});

أو

Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)

لفرز ArrayList يمكنك استخدام التعليمات البرمجية المتكررة التالية:

Collections.sort(studList, new Comparator<Student>(){
    public int compare(Student s1, Student s2) {
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
    }
});

There are a lot of answers for this question already, but none provided me what I was looking for, a map implementation that returns keys and entries sorted by the associated value, and maintains this property as keys and values are modified in the map. Two other questions ask for this specifically.

I cooked up a generic friendly example that solves this use case. This implementation does not honor all of the contracts of the Map interface, such as reflecting value changes and removals in the sets return from keySet() and entrySet() in the original object. I felt such a solution would be too large to include in a answer. If I manage to create a more complete implementation, perhaps I will post it to Github and then to it link in an updated version of this answer.

import java.util.*;

/**
 * A map where {@link #keySet()} and {@link #entrySet()} return sets ordered
 * by associated values based on the the comparator provided at construction
 * time. The order of two or more keys with identical values is not defined.
 * <p>
 * Several contracts of the Map interface are not satisfied by this minimal
 * implementation.
 */
public class ValueSortedMap<K, V> extends HashMap<K, V> {
    protected Map<V, Collection<K>> valueToKeysMap;

    // uses natural order of value object, if any
    public ValueSortedMap() {
        this((Comparator<? super V>) null);
    }

    public ValueSortedMap(Comparator<? super V> valueComparator) {
        this.valueToKeysMap = new TreeMap<V, Collection<K>>(valueComparator);
    }

    public boolean containsValue(Object o) {
        return valueToKeysMap.containsKey(o);
    }

    public V put(K k, V v) {
        V oldV = null;
        if (containsKey(k)) {
            oldV = get(k);
            valueToKeysMap.get(oldV).remove(k);
        }
        super.put(k, v);
        if (!valueToKeysMap.containsKey(v)) {
            Collection<K> keys = new ArrayList<K>();
            keys.add(k);
            valueToKeysMap.put(v, keys);
        } else {
            valueToKeysMap.get(v).add(k);
        }
        return oldV;
    }

    public void putAll(Map<? extends K, ? extends V> m) {
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
            put(e.getKey(), e.getValue());
    }

    public V remove(Object k) {
        V oldV = null;
        if (containsKey(k)) {
            oldV = get(k);
            super.remove(k);
            valueToKeysMap.get(oldV).remove(k);
        }
        return oldV;
    }

    public void clear() {
        super.clear();
        valueToKeysMap.clear();
    }

    public Set<K> keySet() {
        LinkedHashSet<K> ret = new LinkedHashSet<K>(size());
        for (V v : valueToKeysMap.keySet()) {
            Collection<K> keys = valueToKeysMap.get(v);
            ret.addAll(keys);
        }
        return ret;
    }

    public Set<Map.Entry<K, V>> entrySet() {
        LinkedHashSet<Map.Entry<K, V>> ret = new LinkedHashSet<Map.Entry<K, V>>(size());
        for (Collection<K> keys : valueToKeysMap.values()) {
            for (final K k : keys) {
                final V v = get(k);
                ret.add(new Map.Entry<K,V>() {
                    public K getKey() {
                        return k;
                    }

                    public V getValue() {
                        return v;
                    }

                    public V setValue(V v) {
                        throw new UnsupportedOperationException();
                    }
                });
            }
        }
        return ret;
    }
}






java sorting date comparator