Сортировка scala arrayBuffer из TimeStamp

У меня есть эта функция:

def getTime() : ArrayBuffer[Timestamp] = {
    val offset = Timestamp.valueOf("2015-01-01 00:00:00").getTime()
    val end = Timestamp.valueOf("2015-01-02 00:00:00").getTime()
    val diff = end - offset + 1

    val mList = ArrayBuffer[Timestamp]()

    val numRecords = 3
    var i = 0
    while (i < numRecords) {
      val rand = new Timestamp(offset + (Math.random() * diff).toLong)

      mList += rand
      i += 1
    }

  //  mList.toList.sortWith(_ < _); 
   // scala.util.Sorting.quickSort(mList.toArray);
}

Я пытался отсортировать массив, но не смог. Я получаю эту ошибку:

No implicit Ordering defined for java.sql.Timestamp.

Я знаю, что мне нужно определить, как будет выполняться заказ. Есть ли способ легко отсортировать его, как в Java: Collections.sort(list); или есть лучший подход с использованием Scala?


person aselims    schedule 01.05.2015    source источник


Ответы (2)


В качестве альтернативы определите его где-нибудь в своем классе, и все готово:

implicit def ordered: Ordering[Timestamp] = new Ordering[Timestamp] {
    def compare(x: Timestamp, y: Timestamp): Int = x compareTo y
}
getTime().sorted // now this will work just fine
person om-nom-nom    schedule 01.05.2015
comment
Спасибо, Ом, я хотел бы знать, как неявное веселье связано с сортировкой? Концепция позади? - person aselims; 01.05.2015
comment
@aselims о, извините, что оставил это в тумане. Если вы посмотрите, как определяется sorted, вы увидите, что для него неявно требуется один аргумент — ordering, который должен быть определен где-то в области видимости. Для многих типов данных уже есть такое определение, предоставленное scala, поэтому вам не нужно выполнять дополнительную работу, чтобы работать, хотя некоторые типы по-прежнему требуют ручного подключения. Здесь я определил такой порядок для метки времени, используя тот факт, что метка времени на самом деле сопоставима. - person om-nom-nom; 02.05.2015
comment
Обратите также внимание, что def ordered ....; getTime().sorted(ordered) тоже будет работать, я просто добавил немного магии. - person om-nom-nom; 02.05.2015
comment
Спасибо @Om, не могли бы вы дать мне краткую справку, что я могу получить такие секреты scala? - person aselims; 05.05.2015
comment
@aselims не совсем краткое, но каноническое программирование на Scala — это реально - person om-nom-nom; 05.05.2015

mList.sortWith(_.compareTo(_) < 1)

Обратите внимание, что с анонимной функцией вы можете передать явную функцию, которая будет выглядеть так:

def comparator(first: Timestamp, second: Timestamp) = first.compareTo(second) < 1

mList.sortWith(comparator)

В самой Timestamp нет неявного порядка, здесь мы просто сортируем с помощью метода compareTo.

Спасибо @Nick за указание на то, что сортировки по getTime() недостаточно во всех сценариях. Я также рассмотрел метод before, который, как вы ожидаете, будет работать, но он сравнивается только с использованием значения эпохи.

person Sebastiaan van den Broek    schedule 01.05.2015
comment
java.sql.Timestamp может представлять время с точностью до наносекунды, но Timestamp.getTime имеет разрешение в миллисекундах, что приводит к неправильному упорядочению временных меток с интервалом менее 1 мс, что не так уж редко встречается, если ваши временные метки поступают из Postgres и т. д. - person Nick; 05.02.2019
comment
@Ник хорошая мысль, хотя Postgres в настоящее время поддерживает точность только в микросекундах (postgresql.org/docs /current/datatype-datetime.html), как и большинство баз данных. Но все же было бы лучше, если бы порядок был правильным в каждом случае. Я посмотрю, смогу ли я превратить это в ответ. - person Sebastiaan van den Broek; 05.02.2019
comment
Ага! Все, что меньше миллисекундного разрешения, вызовет его в подходе getTime, поскольку микросекунды и т. д. после миллисекунды все сохраняются в компоненте nanos. (Это недавно укусило меня за задницу в некоторых автоматических тестах). Проголосовал за обновление :) - person Nick; 05.02.2019
comment
@Ник, да, я только что перепутал микро и милли ???? в любом случае это хорошо, чтобы избежать проблем. Хотя какой-то сложный класс. - person Sebastiaan van den Broek; 05.02.2019