Home Articles

使用Comparable对ArrayList进行排序

Asked
Viewed 1757 times
3

尝试使用Comparable,我对编程很新,并且从未对ArrayList进行排序 . 我已经看了一些关于堆栈溢出的其他示例并查看了Java Doc但是它相当令人困惑,我不确定如何将它应用到我的程序中

基本上我有两个类,一个Personality类和一个PersonalityList类 . PersonalityList类包含一个名为personalities的Personality数组,它在Array List中存储了许多个性对象 .

我需要按每个人格的投票数对其进行排序 . 方法top(int topValue)应该返回一个长度为topValue的新数组,其中Personality对象的投票率最高 .

我知道我需要在Personality类中使用一些Comparable,但不确定如何执行此操作 .

到目前为止,这是我的PersonalityList类:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collections;

public class PersonalityList
{
    private ArrayList<Personality> personalities; //Create ArrayList of Personality, called personalities.
    private ArrayList<Personality> sortedPersonalities;

    /**
     * Constructor for objects of class PersonalityList
     */
    public PersonalityList()
    {
      personalities = new ArrayList<Personality>(); //Initialise personalities ArrayList.
      sortedPersonalities = new ArrayList<Personality>();
    }

    /**
     * Adds a personality to the ArrayList of Personality, called personalities. 
     */
    public void addPersonality(Personality personality)
    {
       personalities.add(personality);
    }

    /**
     * Returns the number of Personality objects in the ArrayList
     */
    public int getSize()
    {
       return personalities.size(); 
    }

    /**
     * Lists the details of all the Personality objects stored in the ArrayList
     */
    public void list()
    {
       System.out.println("Personality List");

       for(Personality personality : personalities) { //Iterates through each personality in ArrayList
           System.out.println(personality.getDetails()); 
       }

       System.out.println();
    }

     /**
     * Adds one vote to the personality which matches the name entered into the method
     */
    public void voteFor(String name)
    {
         boolean nameFound = false; //Boolean variable to identify if the personality has been found
         int index = 0;

         while (index < personalities.size() && !nameFound) {
             Personality personality = personalities.get(index);
             String compName = personality.getName();

             if (compName.equals(name)) { //Adds a vote if the name is found
                 personality.increaseVotes(1);
                 nameFound = true;
             } 

             index++;
         }

         if (nameFound == false) { //Error message if name not found
             System.out.println(name + " could not be found.");
         }
    }

    /**
     * Removes personalities if they have less votes than the parameter value
     */
    public void shortlist(int minimumVotes) 
    {
        Iterator<Personality> it = personalities.iterator();

        while(it.hasNext()) {
            Personality personality = it.next();
            int currentP = personality.getVotes();

            if (currentP < minimumVotes) { 
                 it.remove();
            }
        }
    }



    /**
     * 
     */
    public Personality top(int topValue)
    {
        int index = 0;
        int listSize = personalities.size();

        if (topValue > listSize) {
            topValue = listSize;
        }

        if(listSize > 0) {

            //Coppies the ArrayList personalities to the sortedPersonalities ArrayList
            while(index < topValue) {
                Personality sortedPersonality = personalities.get(index);
                sortedPersonalities.add(sortedPersonality);
                System.out.println(sortedPersonality.getDetails());
                index++;
            }

            Collections.sort(sortedPersonalities, Collections.reverseOrder(new Personality.votesComparator()));
            System.out.println("Sorted by Votes");
            System.out.println("\t" + people);
        } 
        else {
            System.out.println("No personalities are currently in the Array List");
        }

        return sortedPersonalities ;
    }
}

提前致谢 .

3 Answers

  • 1

    或者您可以使用如下的lambda表达式轻松地在对象之间进行比较:

    Assume that we have a list of Person with their ages;

    List<Person> peopleList =new ArrayList<Person>();
            peopleList.add(new Person("Ann", 23));
            peopleList.add(new Person("Sam", 22));
            peopleList.add(new Person("John", 20));
            peopleList.add(new Person("Watson", 23));
            peopleList.add(new Person("Samuels", 31));
            peopleList.add(new Person("Peter",41));
            peopleList.add(new Person("Harry", 28));
            peopleList.add(new Person("Carter", 19));
            peopleList.add(new Person("Lilly", 26));
            peopleList.add(new Person("Kumar", 12));
            peopleList.add(new Person("Insaf", 51));
    

    我们可以使用 Comparator 界面比较这些人的年龄

    Comparator<Person> personComparatorByAgeUsingStream =(Person b1,Person b2)->{return ((Integer)b1.getAge()).compareTo((Integer)b2.getAge());};
    

    然后我们可以将这些人分类为List:

    List<Person> streamSort= peopleList
                            .stream()
                .sorted(personComparatorByAgeUsingStream).collect(Collectors.toList());
    
     streamSort.forEach(x->{System.out.println(x.getName()+" is "+x.getAge()+" years old.");});
    
  • 1

    这是我尝试显示为自定义对象创建Comparator的完整示例:

    /*
    **  Use the Collections API to sort a List for you.
    **
    **  When your class has a "natural" sort order you can implement
    **  the Comparable interface.
    **
    **  You can use an alternate sort order when you implement
    **  a Comparator for your class.
    */
    import java.util.*;
    
    public class Person implements Comparable<Person>
    {
        String name;
        int age;
    
        public Person(String name, int age)
        {
            this.name = name;
            this.age = age;
        }
    
        public String getName()
        {
            return name;
        }
    
        public int getAge()
        {
            return age;
        }
    
        public String toString()
        {
            return name + " : " + age;
        }
    
        /*
        **  Implement the natural order for this class
        */
        public int compareTo(Person p)
        {
            return getName().compareTo(p.getName());
        }
    
        static class AgeComparator implements Comparator<Person>
        {
            public int compare(Person p1, Person p2)
            {
                return p1.getAge() - p2.getAge();
            }
        }
    
        public static void main(String[] args)
        {
            List<Person> people = new ArrayList<Person>();
            people.add( new Person("Homer", 38) );
            people.add( new Person("Marge", 35) );
            people.add( new Person("Bart", 15) );
            people.add( new Person("Lisa", 13) );
    
            // Sort by natural order
    
            Collections.sort(people);
            System.out.println("Sort by Natural order");
            System.out.println("\t" + people);
    
            // Sort by reverse natural order
    
            Collections.sort(people, Collections.reverseOrder());
            System.out.println("Sort by reverse natural order");
            System.out.println("\t" + people);
    
            //  Use a Comparator to sort by age
    
            Collections.sort(people, new Person.AgeComparator());
            System.out.println("Sort using Age Comparator");
            System.out.println("\t" + people);
    
            //  Use a Comparator to sort by descending age
    
            Collections.sort(people, Collections.reverseOrder(new Person.AgeComparator()));
            System.out.println("Sort using Reverse Age Comparator");
            System.out.println("\t" + people);
        }
    }
    
  • 0

    列表可以包含两次元素 . 在这种情况下,谁将成为第一个谁是第二个?答案很模糊,因此他们决定不通过比较器对列表进行排序 .

    也许你正在寻找 TreeSet (谁拥有可比性的自然支持)? Set 不能多次包含元素 .

    你可能会说: Hey, i realy often have collections without the need of duplicates but i always use lists! . 是的,这是一个广泛传播的错误 .

    请使用Set让世界知道:没有重复 .

Related