Reputation: 1250
In my program I have a HashSet<HashSet<Integer>>
, at then end of my program I'm printing the contents using the following statement,
System.out.println("Groups: " + allSets.toString());
It shows me this,
Groups: [[17], [19], [2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21], [11], [13]]
My answer is okay, but I would like to see it in sorted like,
Groups: [[2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21], [11], [13], [17], [19]]
I'm inserting into the Set all the single numbered sets in sorted order and I have to insert the big set at the end.
I tried with TreeSet
but it doesn't work, (got some exceptions
).
I solved my problem using List
instead of Set
,
I'm wondering, is there any way to get the same ordered output by using Set
?
Upvotes: 1
Views: 1645
Reputation: 441
Unfortunately I'm unable to comment on answer. But accepted answer could not accurate. You should be very careful with comparators when using Tree in java. Once your comparator returns 0 it's assumed objects are equal, so will not be added into Tree.
If your sets expected to contain all unique numbers, just ignore this answer!
Otherwice: Comparator proposed by Louis Wasserman compares by first element only! So in case Try next code to test it:
SortedSet<Integer> s1 = new TreeSet<>(Arrays.asList(13, 14, 15, 16, 17));
SortedSet<Integer> s2 = new TreeSet<>(Arrays.asList(13, 19));
SortedSet<Integer> s3 = new TreeSet<>(Arrays.asList(13, 133));
SortedSet<Integer> s4 = new TreeSet<>(Arrays.asList(110, 13));
SortedSet<Integer> s5 = new TreeSet<>(Collections.singletonList(13));
SortedSet<Integer> s6 = new TreeSet<>(Arrays.asList(13,16));
SortedSet<Integer> s7 = new TreeSet<>(Arrays.asList(13,17));
SortedSet<SortedSet<Integer>> s = new TreeSet<SortedSet<Integer>>(
Comparator.comparingInt(SortedSet::first));
s.addAll(Arrays.asList(s1, s2, s3, s4, s5, s6, s7));
System.out.println(s);
This will be:
[[13, 14, 15, 16, 17]]
Is this something you’re expecting?
If you want to go with TreeSet you need more strict comparator, like: (compares by size descending, then same-sizes are compared by items one by one)
new TreeSet<>(((Comparator<Set<Integer>>) (o1, o2) -> o2.size() - o1.size()).thenComparing((o1, o2) -> {
Iterator<Integer> i1 = o1.iterator();
Iterator<Integer> i2 = o2.iterator();
while (i1.hasNext() && i2.hasNext()) {
Integer n1 = i1.next();
Integer n2 = i2.next();
if (!n1.equals(n2)) {
return n1 - n2;
}
}
return 0;
}));
You probably might want change the order of comparing (by size after by items.
Upvotes: 1
Reputation: 790
HashSet<HashSet<Integer>> allSets = new HashSet<>();
List<Set<Integer>> out=allSets.stream().
sorted((x, y) -> x.iterator().next() - y.iterator().next()).
collect(Collectors.toList());
Upvotes: 1
Reputation: 173
I'm working with the assumption that you're putting "values" in the set in sorted order, HashSet itself doesn't preserve the order of the insertion, but you could use LinkedHashSet, from the doc:
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)."
You could use this behavior during printing.
Upvotes: 0
Reputation: 198321
You can use a TreeSet
for the outer set, you just need to give it a valid comparator. I would recommend something like
SortedSet<SortedSet<Integer>> outerSet = new TreeSet<SortedSet<Integer>>(
Comparator.comparingInt(SortedSet::first));
(assuming Java 8).
Upvotes: 6