简体   繁体   中英

Java HashSet - is there a way to specify the order in which elements will be displayed?

I have just started debugging some software that has been written in Java, and on one of the web pages, there is drop down list that lists the days of the week.

When expanded, the list shows the days of the week in the drop down Sunday through to Saturday. However, when the drop down is not selected/ expanded, it's text shows:

Mo-Su-Tu-We-Th-Fr-Sa

ie the order of the days displayed on the button when it's not selected/ expanded is incorrect.

My thinking is that this is probably because the class has been written using a HashSet object to display the days:

private List<String> allDays = Arrays.asList(SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY);
...
private Set<String> currentDays = new HashSet<String>(allDays);

As I understand, with HashSets, you cannot guarantee the order in which its elements will be retrieved/ displayed- is that correct?

I tried changing the type from HashSet to ArrayList , so that I could set definite positions for each day of the week within the collection, but this caused other compile errors elsewhere in the code. My thought is that there must be design reasons for why it has been implemented as a HashSet , rather than an ordered list, so I don't really want to refactor the code to change the object's type.

So is there a way that I can specify the output of the HashSet where it's used in this case, in order to predetermine the order in which its elements will be displayed?

Can I cast it to a type that is an ordered list, ie an ArrayList / some other structured data type, or can I specifically tell the HashSet object in what order I want to display its elements?

You can Use LinkedHashSet it keeps order of elements.

Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set. (An element e is reinserted into a set s if s.add(e) is invoked when s.contains(e) would return true immediately prior to the invocation.)

LinkedHashSet

As I understand, with HashSets, you cannot guarantee the order in which its elements will be retrieved/ displayed- is that correct?

Correct.

So is there a way that I can specify the output of the HashSet where it's used in this case, in order to predetermine the order in which its elements will be displayed?

No. The toString() method "outputs" the element in an order that you cannot alter.

However, you could write a method that displayed the elements of a HashSet in a specific order. For example:

private static String[] DAYS = {"Sun", "Mon", "Tue", "Wed", "Thu", 
                                "Fri", "Sat"};

String printDays(Set<String> days) {
    StringBuilder sb = new StringBuilder();
    for (String s: DAYS) {
        if (days.contains(s)) {
            if (sb.length() == 0) {
                sb.append("{" + s);
            } else {
                sb.append(", " + s);
            }
         }
     }
     sb.append("}");
     return sb.toString();
 }

That can easily be modified to work with an enum ... and the method could be a static method of the enum class.

First of all, those days of the week must be enum values. And if you do that, you'll be able to use:

EnumSet.allOf(DaysOfWeekEnum.class); which would display all your days in the order in which they were defined in the enum.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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