【问题标题】:Sort List<T> based on String DateTime根据 String DateTime 对 List<T> 进行排序
【发布时间】:2020-11-18 09:01:06
【问题描述】:

我想根据字符串形式的UTC DateTime对列表进行降序排序。

我的班级

    data class CartEntity( val itemId: String,  var itemName: String, var createdDate: String)

在这个 createdDate 中是 "2020-07-28T14:28:52.877Z"

我尝试过的

    const val UTC_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

    Collections.sort(list, object : Comparator<CartEntity> {
        var f: DateFormat =
            SimpleDateFormat(
                AppConstants.UTC_FORMAT, Locale.ENGLISH
            )
    
        override fun compare(o1: CartEntity?, o2: CartEntity?): Int {
            return try {
                val firstitem = f.parse(o1?.createdDate!!)
                val seconditem = f.parse(o2?.createdDate!!)
                firstitem.compareTo(seconditem)
            } catch (e: ParseException) {
                throw IllegalArgumentException(e)
            }
        }
    
    })

但仍然按降序排序并没有按预期工作

【问题讨论】:

  • 您面临的问题是什么?请添加您的输入和输出,以便更好地理解问题。

标签: kotlin


【解决方案1】:

这可以使用以下方法来完成。

import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class Tester {

    static class Car {

        private String date;

        String getDate() {
            return this.date;
        }

        void setDate(String date) {
            this.date = date;
        }

        @Override
        public String toString() {
            return date;
        }

        // Imagine if you keep date not as strings
        ZonedDateTime toDateTime(){
            return ZonedDateTime.parse(this.date);
        }
    }

    public static void main(String[] args) {

        Car first = new Car();
        first.setDate("2020-07-28T14:28:52.877Z");

        Car second = new Car();
        second.setDate("2010-07-28T14:28:52.877Z");

        Car third = new Car();
        third.setDate("2021-07-28T14:28:52.877Z");

        List<Car> cars = Arrays.asList(first, second, third);

        List<Car> sorted = cars.stream().sorted(Comparator.nullsLast(
                (current, next) -> {
                    ZonedDateTime currentDate = ZonedDateTime.parse(current.getDate());
                    ZonedDateTime nextDate = ZonedDateTime.parse(next.getDate());

                    return nextDate.compareTo(currentDate);
                })).collect(Collectors.toList());
    }
}

如果您将日期保留为常规 Date 对象,则使用它们会更容易,并且上面的代码可以简化一点。

List<Car> sorted = cars.stream()
                               .sorted(Comparator.comparing(Car::toDateTime, Comparator.nullsLast(Comparator.reverseOrder())))
                               .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    你的代码工作得很好@Charwaka。

    data class CartEntity(val itemId: String, var itemName: String, var createdDate: String)
    const val UTC_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
    fun main() {
        val list = mutableListOf<CartEntity>().apply {
            add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T14:28:52.877Z"))
            add(CartEntity(itemId = "", itemName = "", createdDate = "2020-09-28T14:28:52.877Z"))
            add(CartEntity(itemId = "", itemName = "", createdDate = "2020-08-28T14:28:52.877Z"))
            add(CartEntity(itemId = "", itemName = "", createdDate = "2020-04-28T14:28:52.877Z"))
        }
        Collections.sort(list, object : Comparator<CartEntity> {
            var f: DateFormat = SimpleDateFormat(UTC_FORMAT, Locale.ENGLISH)
    
            override fun compare(o1: CartEntity, o2: CartEntity): Int {
                return try {
                    val firstitem = f.parse(o1.createdDate)
                    val seconditem = f.parse(o2.createdDate)
                    seconditem.compareTo(firstitem)
                } catch (e: ParseException) {
                    throw IllegalArgumentException(e)
                }
            }
        })
        list
    }
    

    输出:

    CartEntity(itemId=, itemName=, createdDate=2020-09-28T14:28:52.877Z), 
    CartEntity(itemId=, itemName=, createdDate=2020-08-28T14:28:52.877Z), 
    CartEntity(itemId=, itemName=, createdDate=2020-07-28T14:28:52.877Z), 
    CartEntity(itemId=, itemName=, createdDate=2020-04-28T14:28:52.877Z)
    

    @Animesh Sahu 的代码也可以使用!

    val 格式:DateFormat = SimpleDateFormat(AppConstants.UTC_FORMAT, Locale.ENGLISH) list.sortByDescending { format.parse(it.createdDate) }

    【讨论】:

    • 你可以试试 add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T17:41:47.836Z")) add(CartEntity(itemId = " ", itemName = "", createdDate = "2020-07-28T17:41:53.828Z")) add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T17:41:55.792Z ")) add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T17:42:00.413Z"))
    • CartEntity(itemId=, itemName=, createdDate=2020-07-28T17:42:00.413Z), CartEntity(itemId=, itemName=, createdDate=2020-07-28T17:41:55.792Z ), CartEntity(itemId=, itemName=, createdDate=2020-07-28T17:41:53.828Z), CartEntity(itemId=, itemName=, createdDate=2020-07-28T17:41:47.836Z)
    【解决方案3】:

    在 kotlin 风格中,您可以使用标准库函数(以下习语):

    从您要排序的列表中创建一个新的排序列表

    fun main() {
        val list = listOf<CartEntity>(
            CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T14:28:52.877Z"),
            CartEntity(itemId = "", itemName = "", createdDate = "2020-09-28T14:28:52.877Z"),
            CartEntity(itemId = "", itemName = "", createdDate = "2020-08-28T14:28:52.877Z"),
            CartEntity(itemId = "", itemName = "", createdDate = "2020-04-28T14:28:52.877Z"),
        )
    
        val format: DateFormat = SimpleDateFormat(AppConstants.UTC_FORMAT, Locale.ENGLISH)
    
        val sortedList = list.sortedByDescending { format.parse(it.createdDate) }
    
        println(sortedList)  // `sortedList` is sorted out list, the `list` is holding the original order
    }
    

    原始列表进行排序(列表应该是可变的):

    fun main() {
        val list = mutableListOf<CartEntity>(
            CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T14:28:52.877Z"),
            CartEntity(itemId = "", itemName = "", createdDate = "2020-09-28T14:28:52.877Z"),
            CartEntity(itemId = "", itemName = "", createdDate = "2020-08-28T14:28:52.877Z"),
            CartEntity(itemId = "", itemName = "", createdDate = "2020-04-28T14:28:52.877Z"),
        )
    
        val format: DateFormat = SimpleDateFormat(AppConstants.UTC_FORMAT, Locale.ENGLISH)
        list.sortByDescending { format.parse(it.createdDate) }
    
        println(list)  // `list` is sorted out list
    }
    

    【讨论】:

    • 显然不应鼓励使用 SimpleDateFormat 的惯用答案。首选 java.time.format.DateTimeFormatter.ISO_DATE_TIME
    • @drekbour 在性能方面可能是一个更好的选择,但它是在 API 级别 26 中添加的,因此为了向后兼容,这可能不是那么糟糕的选择,否则可以进行 if 检查和根据 API 级别使用正确的格式化程序。 stackoverflow.com/a/53781196/11377112 SimpleDateFormat 在 API 级别 26 以下仍然更可取。
    猜你喜欢
    • 2019-07-02
    • 2010-10-17
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 2021-12-09
    • 2017-01-12
    相关资源
    最近更新 更多