Hello! What's the best way to get next item in Set...
# android
o
Hello! What's the best way to get next item in Set? For example, I have Set{2,8,3,4}. And If I take item "8", how can I get an item with number "3" from the list ? I can't just find item 3, I need find solution to take next item in Set. The main goal to add previous and next button on Details screen to be able going through the set.
g
You can use iterator for this
d
Sets dont have a defined ordering. Unless they are NavigableSet, I.e. TreeSet, it will be arbitrary.
✔️ 1
g
Default set implementation used in kotlin for generic set builder is sorted, but I agree, Set probably not the best data structure for this
o
Ok, thanks, I'll try to use NavigableSet
a
Whichever
Iterable<Int>
you use:
Copy code
val next: Int? = iterable.dropWhile { it != 8 }.getOrNull(1)
So would apply to all
Set
implementations, or
List
implementations.
g
Not the most efficient implementation tho, it creates intermediate list
a
I took into account the use case.
The main goal to add previous and next button on Details screen to be able going through the set.
g
Yes, I understand, but it can be achieved without intermediate collection creation (many ways actually)
a
Still, how do you suggest using the
NavigableSet
? And why not a
SortedSet
?
g
SortedSet is an interface NavigatableSet is an implementation of this interface
d
That's trivial. The point was that set makes no sense.
NavigableSet is an interface also
☝️ 1
g
Yes, you right, sorry
a
If you wanted to avoid intermediate list creation:
Copy code
val next: Int? = iterable
        .asSequence()
        .dropWhile { it != 8 }
        .elementAtOrNull(1)
g
TreeSet is implementation
Yes, it will also work, also you can do the same with iterator
a
I'm just not sure what you're suggesting, trivial or not. Are you suggesting a Java style
while
loop?
d
But it still doesn't make sense because elements will be displayed in arbitrary order. Unless that's what he wants, I'm recommending to use something that does have a defined ordering. The ordering of your idea is only defined if the set is sorted.
o
What's the best sorted set in my case?
a
I just said
iterable
So it works for the
TreeSet
or a
List
.
d
Well, we've gone off and assumed that you have integers in your set. Is that right?
a
I would use a
List
.
o
YEs
d
Yeah if you can use a list, use a list.
o
I can't use List, because I need to accumulate only unique data
a
Even if you have a set then:
Copy code
val list: List<Int> = set.sortedBy { it } 
    
    val next: Int? = list
        .asSequence()
        .dropWhile { it != 8 }
        .elementAtOrNull(1)
sort by whatever makes sense
but a set sorted in to immutable list is still unique
In addition, if you are not using
int
and are sorting something else, it is far easier to specify that sort order than support
Comparable
, or write a
Comparator
which is what you need to do if you use
TreeSet
.
g
You can remove duplicates from list using extension function distinct()
o
Thanks guys, I chose TreeSet. And now I can take lower and higher item. It's really convenient. But now I'm stuck with implementing Comparable. Because I use in Set some Objects (Int was for understanding a problem). What's the best way to implement compareTo method? In my object I have field "String" (hex data).
a
Called it!
it is far easier to specify that sort order than support
Comparable
, or write a
Comparator
which is what you need to do if you use
TreeSet
.
This is how you can specify it
Copy code
val set = TreeSet<Int> { a, b -> a.compareTo(b) }
✔️ 1
And for more complex object:
Copy code
class MyClass(val field1: String, val field2: Int)

    val byField1 = Comparator<MyClass> { o1, o2 -> o1.field1.compareTo(o2.field1) }
    val byField2 = Comparator<MyClass> { o1, o2 -> o1.field2.compareTo(o2.field2) }
    val byField2Descending = byField2.reversed()

    val set = TreeSet<MyClass>(byField1.then(byField2Descending))
o
I tried to do it in your error, but I had an error
a
say what?
o
my set is MutableSet
a
you need to specify the sort order, e.g.
sortedBy { it.someField }
it
worked for
Int
o
ok, you are right
a
but still, maybe go with the treeset, the comparators don't look too bad in Kotlin
o
Yes, TreeSet was good idea, I just had a problem with a comporator. I'll try you implementation for compareTo. Thanks
a
You can also give the same comparators to sort
set.sortedWith(byField1.then(byField2Descending))
just FYI
👍 1
o
I implemented Comparable in my object. TreeSet works fine with this implementation: override fun compareTo(other: BeaconData): Int { return this.data.compareTo(other.data) } Thanks )