使用Comparable对ArrayList进行排序

时间:2015-11-22 21:34:56

标签: java sorting arraylist

尝试使用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 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分:1)

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

假设我们有一个人的年龄列表;

       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<Person> streamSort= peopleList
                        .stream()
            .sorted(personComparatorByAgeUsingStream).collect(Collectors.toList());

 streamSort.forEach(x->{System.out.println(x.getName()+" is "+x.getAge()+" years old.");});

答案 2 :(得分:0)

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

也许您正在寻找TreeSet(谁拥有可竞争的自然支持)? Set不能多次包含元素。

你可能会说:嘿,我真的经常收藏而不需要重复,但我总是使用列表!。是的,这是一个广泛传播的错误。

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