0

I know this character (:) is meaningless in my statement, but I wanted to explain what I want. I want to sort a lot of hashmaps adding Arraylist and using sortedBy but I cant because my values return strings.

Here is my code:

newReference.addValueEventListener(object : ValueEventListener{

            override fun onDataChange(p0: DataSnapshot) {

                chatMessages.clear()

                for(ds in p0.child(playerIDmatchWhoIs).children){

                    var hashMap = ds.getValue() as HashMap<String, String>
                    var datetime = hashMap.get("datetime").toString()
                    var usermail = hashMap.get("usermail")
                    var usermessage = hashMap.get("usermessage")

                    chatMessages.add("${usermail}: ${usermessage}")
                    recyclerViewAdapter.notifyDataSetChanged()

                }
            }
        })

(I want to sort this hashMap, it has datetime value but is returning string.)

println(hashMap): I/System.out: {datetime=1574807563747, usermessage=jmjgmhg, usermail=1@gmail.com}
David Buck
  • 3,752
  • 35
  • 31
  • 35
commandiron
  • 1,019
  • 1
  • 9
  • 25

1 Answers1

0

I assume that chatMessages is of type List<String>. This is generally bad because you cannot to anything with strings. I would suggest you to create a data class which contains all information about a chat message, like so:

data class ChatMessage(val dateTime: Int, val userMail: String?, val userMessage: String?) : Comparable<ChatMessage> {
    override fun compareTo(other: ChatMessage) = this.dateTime.compareTo(other.dateTime)
}

As you can see, this class implements the Comparable<ChatMessage> interface. If you then define the chatMessages list like so

private val chatMessages = mutableListOf<ChatMessage>()

you can call chatMessages.sort() which will then sort the list according to dateTime (see the implementation of compareTo in ChatMessage). The final code would look like that:

data class ChatMessage(val dateTime:Int?, val userMail: String?, val userMessage: String?) : Comparable<ChatMessage> {
    override fun compareTo(other: ChatMessage) = this.dateTime.compareTo(other.dateTime)
}

private val chatMessages = mutableListOf<ChatMessage>()

fun yourCode() {
    newReference.addValueEventListener(object : ValueEventListener {

        /* Use proper variable naming. Nobody will understand, what p0 is, but if you name
        it dataSnapshot, everyone knows at a glance. */
        override fun onDataChange(dataSnapshot: DataSnapshot) {

            chatMessages.clear()

            // Again, what is ds exactly? Name it properly.
            for (ds in dataSnapshot.child(playerIDmatchWhoIs).children) {
                // Kotlin recommends to use val instead of var.
                // This way, you know that your variables cannot be modified unless you want them to be modified.
                val hashMap = ds.getValue() as HashMap<String, String>

                // use indexing instead of the get() method
                val dateTime = hashMap["datetime"]
                val userMail = hashMap["usermail"]
                val userMessage = hashMap["usermessage"]

                // TODO: Handle null values properly
                chatMessages.add(ChatMessage(dateTime!!.toInt(), userMail, userMessage))
                recyclerViewAdapter.notifyDataSetChanged()

            }

            chatMessages.sort()
        }
    })
}

This assumes that you want to store your timestamp as an integer. However, I would rather recommend to use a time library like java.time (built into java). In that case, you can use java.time.Instant which has many more possibilities to handle time and all the difficulties to handle time.

Read more about java.time.Instant in the Android docs. If you want to learn how to parse a String to java.time.Instant, this might be interesting.

vatbub
  • 2,713
  • 18
  • 41