简体   繁体   English

如何根据这些条件对对象的HashSet进行排序?

[英]How do I sort a HashSet of objects based on these criteria?

I've thrown together a SSCCE here: 我在这里汇集了SSCCE:

House.java : House.java:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class House {

    private Status currentStatus;
    private String city;
    private Date date;

    public enum Status { AVAILABLE, 
                         SOLD, 
                         CONTINGENT 
    }

    public House(Status s, String c, String d) throws ParseException {
        currentStatus = s;
        city = c;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        date = sdf.parse(d);
    }
}

SortingTest.java : SortingTest.java:

import java.text.ParseException;
import java.util.HashSet;
import sortingtest.House.Status;    

public class SortingTest {


    public static void main(String[] args) throws ParseException {
        HashSet<House> houses = new HashSet<House>();
        houses.add(new House(Status.AVAILABLE, "New York City", "2007-11-11"));
        houses.add(new House(Status.SOLD, "Los Angeles", "2005-06-11"));
        houses.add(new House(Status.AVAILABLE, "Chicago", "2012-05-03"));
        houses.add(new House(Status.CONTINGENT, "Portland", "2007-10-11"));

        //Sort HashSet of House objects by criteria listed below      

        //sort by Status.AVAILABLE
            //call sort
            //System.out.println("Sorted by available");
            //iterate set and print out sorted houses

        //sort by Status.SOLD
            //call sort
            //System.out.println("Sorted by sold");
            //iterate set and print out sorted houses

        //sort by Status.CONTINGENT
            //call sort
            //System.out.println("Sorted by contingent");
            //iterate set and print out sorted houses

        //sort by City
            //call sort
            //System.out.println("Sorted alphabetically by City");
            //iterate set and print out sorted houses

        //sort by City
            //call sort
            //System.out.println("Sorted reverse alphabetically by City");
            //iterate set and print out sorted houses

        //sort by Date (newest)
            //call sort
            //System.out.println("Sorted by newest date (fewest days on market)");
            //iterate set and print out sorted houses

        //sort by Date (oldest)
            //call sort
            //System.out.println("Sorted oldest date (most days on market)");
            //iterate set and print out sorted houses
    }
}

So ultimately I'm wanting to create a SetSorter class where I can just call a method that will return the Set sorted in a particular format. 因此,最终,我想创建一个SetSorter类,在这里我可以调用一个将返回以特定格式排序的Set的方法。

In case you didn't want to read the comments in the code, I'm wanting to sort based on: 如果您不想阅读代码中的注释,我想根据以下内容进行排序:

  • Status.AVAILABLE 状态。
  • Status.SOLD 状态。
  • Status.Contingent 状态或然
  • City (alphabetically) 城市(按字母顺序)
  • City (reverse alphabetically) 城市(按字母顺序反向)
  • Date (fewest days on market) 日期(市场上的最近几天)
  • Date (most days on market) 日期(市场上最多的几天)

I've done a bit of reading on it, and it looks like people suggest making it into a TreeSet for sorting and using a comparator. 我已经对其进行了一些阅读,似乎有人建议将其放入TreeSet中以进行排序和使用比较器。 I've seen multiple examples where people either create a separate class just for the comparator or they make the specified class implement comparable. 我已经看到了多个示例,其中人们要么为比较器创建一个单独的类,要么使指定的类实现可比。

What I haven't seen is someone write an extra class to handle all of the sorting. 我还没有看到有人写一个额外的类来处理所有排序。 Is this possible? 这可能吗? If so, can someone show me where to start? 如果是这样,有人可以告诉我从哪里开始? These seems like slightly more complicated comparisons than typical integer comparisons. 这些比较似乎比典型的整数比较稍微复杂一些。

Edit for clarification 编辑以澄清

When sorting by Status.AVAILABLE I would like the Set to have the objects appear by: 当按Status.AVAILABLE排序时,我希望Set通过以下方式显示对象:

  • Status.AVAILABLE (on top/first) 状态。可用(在顶部/第一)
  • Status.CONTINGENT (after Status.AVAILABLE/second) Status.CONTINGENT(在Status.AVAILABLE /秒之后)
  • Status.SOLD (after Status.CONTINGENT/last) Status.SOLD(在Status.CONTINGENT /最后之后)

When sorting by Status.CONTINGENT I want the set sorted as follows: 当按Status.CONTINGENT排序时,我希望集合按以下顺序排序:

  • Status.CONTINGENT 状态.CONTINGENT
  • Status.SOLD 状态。
  • Status.AVAILABLE 状态。

When sorting by Status.SOLD I want the set sorted as follows: 当按Status.SOLD排序时,我希望集合按以下顺序排序:

  • Status.SOLD 状态。
  • Status.CONTINGENT 状态.CONTINGENT
  • Status.AVAILABLE 状态。

Edit #2 Ultimate Goal : 编辑#2最终目标

I would like to have a class where I can simply call methods to sort the set. 我想拥有一个可以在其中简单地调用方法对集合进行排序的类。

Ie: 即:

//sort by date
SetSorter.sortByData(treeSet);    //returns TreeSet sorted by date

//sort by city
SetSorter.sortByCity(treeSet);    //returns TreeSet sorted by City

//sort by other criteria 

Edit #3 编辑#3

class SortByCity implements Comparator<House> {
    @Override
    public int compare(House h1, House h2) {
        return h1.getCity().compareTo(h1.getCity());
    } 
}


houses = new TreeSet(new SortByCity());

I think this would be a simple way of doing this, but these would all be little classes and (in my opinion) look messy. 我认为这是执行此操作的简单方法,但是这些全都是小类,并且(在我看来)看起来很凌乱。 Who wants to have 7 mini classes inside of a .java? 谁想在.java中拥有7个迷你类?

Can someone provide some alternative examples for me to look at? 有人可以提供一些替代示例供我查看吗?

Here are some samples on sorting. 以下是一些排序示例。 I haven't performed the date or reverse alphabet sorting (that's an assignment). 我尚未执行日期或反向字母排序(这是一项任务)。 Note the inline comment about comparing two houses to value 0 ! 请注意有关将两个房屋的值比较为0的内联注释!

public class HouseSorter {

    enum Status {
        SOLD, AVAILABLE, CONTINGENT;
    }

    /**
     * Immutable house (if a house is sold or not does not change a house, use a
     * Map instead).
     */
    private static class House {
        private final String city;

        House(String city) {
            this.city = city;
        }

        public String getCity() {
            return city;
        }

        @Override
        public String toString() {
            return "House in " + city;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (!House.class.isAssignableFrom(obj.getClass())) {
                return false;
            }
            return this.city.equalsIgnoreCase(((House) obj).city);
        }

        @Override
        public int hashCode() {
            return city.hashCode();
        }
    }

    public static SortedSet<House> sortAlphabetically(Set<House> houses) {
        TreeSet<House> sortedHouses = new TreeSet<House>(
                new Comparator<House>() {
                    @Override
                    public int compare(House o1, House o2) {
                        return o1.getCity().compareTo(o2.getCity());
                    }
                });
        sortedHouses.addAll(houses);
        return sortedHouses;
    }

    public static SortedSet<House> sortByStatus(
            final Map<House, Status> houseStatusMap) {
        TreeSet<House> sortedHouses = new TreeSet<House>(
                new Comparator<House>() {
                    @Override
                    public int compare(House o1, House o2) {
                        int compareByStatus = houseStatusMap.get(o1).compareTo(
                                houseStatusMap.get(o2));
                        if (compareByStatus != 0) {
                            return compareByStatus;
                        }
                        // you need an additional compare, until none of the
                        // houses compare with result 0
                        // otherwise the houses would be equal and therefore
                        // removed from the set
                        return o1.getCity().compareTo(o2.getCity());
                    }
                });
        sortedHouses.addAll(houseStatusMap.keySet());
        return sortedHouses;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        final Map<House, Status> houseStatusMap = new HashMap<House, Status>();
        House house0 = new House("Beverwijk");
        houseStatusMap.put(house0, Status.SOLD);
        House house1 = new House("Opmeer");
        houseStatusMap.put(house1, Status.SOLD);
        House house2 = new House("Amstelveen");
        houseStatusMap.put(house2, Status.AVAILABLE);
        House house3 = new House("Haarlem");
        houseStatusMap.put(house3, Status.CONTINGENT);

        System.out.println(sortAlphabetically(houseStatusMap.keySet()));
        System.out.println(sortByStatus(houseStatusMap));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM