https://kotlinlang.org logo
#android
Title
# android
o

Oleh Ponomarenko

02/26/2019, 11:57 AM
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

gildor

02/26/2019, 11:58 AM
You can use iterator for this
d

Dico

02/26/2019, 12:00 PM
Sets dont have a defined ordering. Unless they are NavigableSet, I.e. TreeSet, it will be arbitrary.
✔️ 1
g

gildor

02/26/2019, 12:02 PM
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

Oleh Ponomarenko

02/26/2019, 12:04 PM
Ok, thanks, I'll try to use NavigableSet
a

Alan Evans

02/26/2019, 12:05 PM
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

gildor

02/26/2019, 12:09 PM
Not the most efficient implementation tho, it creates intermediate list
a

Alan Evans

02/26/2019, 12:11 PM
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

gildor

02/26/2019, 12:14 PM
Yes, I understand, but it can be achieved without intermediate collection creation (many ways actually)
a

Alan Evans

02/26/2019, 12:14 PM
Still, how do you suggest using the
NavigableSet
? And why not a
SortedSet
?
g

gildor

02/26/2019, 12:15 PM
SortedSet is an interface NavigatableSet is an implementation of this interface
d

Dico

02/26/2019, 12:16 PM
That's trivial. The point was that set makes no sense.
NavigableSet is an interface also
☝️ 1
g

gildor

02/26/2019, 12:16 PM
Yes, you right, sorry
a

Alan Evans

02/26/2019, 12:17 PM
If you wanted to avoid intermediate list creation:
Copy code
val next: Int? = iterable
        .asSequence()
        .dropWhile { it != 8 }
        .elementAtOrNull(1)
g

gildor

02/26/2019, 12:17 PM
TreeSet is implementation
Yes, it will also work, also you can do the same with iterator
a

Alan Evans

02/26/2019, 12:19 PM
I'm just not sure what you're suggesting, trivial or not. Are you suggesting a Java style
while
loop?
d

Dico

02/26/2019, 12:20 PM
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

Oleh Ponomarenko

02/26/2019, 12:20 PM
What's the best sorted set in my case?
a

Alan Evans

02/26/2019, 12:21 PM
I just said
iterable
So it works for the
TreeSet
or a
List
.
d

Dico

02/26/2019, 12:21 PM
Well, we've gone off and assumed that you have integers in your set. Is that right?
a

Alan Evans

02/26/2019, 12:21 PM
I would use a
List
.
o

Oleh Ponomarenko

02/26/2019, 12:21 PM
YEs
d

Dico

02/26/2019, 12:22 PM
Yeah if you can use a list, use a list.
o

Oleh Ponomarenko

02/26/2019, 12:22 PM
I can't use List, because I need to accumulate only unique data
a

Alan Evans

02/26/2019, 12:22 PM
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

gildor

02/26/2019, 12:35 PM
You can remove duplicates from list using extension function distinct()
o

Oleh Ponomarenko

02/27/2019, 11:04 AM
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

Alan Evans

02/27/2019, 1:18 PM
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

Oleh Ponomarenko

02/27/2019, 1:25 PM
I tried to do it in your error, but I had an error
a

Alan Evans

02/27/2019, 1:26 PM
say what?
o

Oleh Ponomarenko

02/27/2019, 1:27 PM
my set is MutableSet
a

Alan Evans

02/27/2019, 1:28 PM
you need to specify the sort order, e.g.
sortedBy { it.someField }
it
worked for
Int
o

Oleh Ponomarenko

02/27/2019, 1:29 PM
ok, you are right
a

Alan Evans

02/27/2019, 1:29 PM
but still, maybe go with the treeset, the comparators don't look too bad in Kotlin
o

Oleh Ponomarenko

02/27/2019, 1:30 PM
Yes, TreeSet was good idea, I just had a problem with a comporator. I'll try you implementation for compareTo. Thanks
a

Alan Evans

02/27/2019, 1:31 PM
You can also give the same comparators to sort
set.sortedWith(byField1.then(byField2Descending))
just FYI
👍 1
o

Oleh Ponomarenko

02/27/2019, 1:46 PM
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 )