【问题标题】:Sort List in place by a variable deep down in the structure in a complex Object在复杂对象的结构中按变量对列表进行排序
【发布时间】:2020-02-25 06:20:59
【问题描述】:

我有一个从 json 解析的复杂“订单”对象。在结构深处的某个地方,我有 orderDate。我只能将其提取为字符串!现在我尝试对订单列表进行排序。

我的想法是创建一个新的 List,其中的数组包含两个元素,第一个是 Order 对象本身,第二个是解析为 Date 对象的 Date。 例如。新对象[]{order, new Date(order.getOrderDate())}。然后按第二个元素排序,然后解析回 List 并返回。但这会创建两个新的 List 并且没有到位。

另一个想法是创建一个像这样排序的自定义比较器

    orders.sort(new Comparator<Order>() {
        @Override
        public int compare(Order o1, Order o2) {
            return new Date(o1.getOrderDate()).compareTo(new Date(o2.getOrderDate()));
        }
    });

但是第二个变体会创建很多新的日期对象。每个条目都有很多次最坏的情况。

有没有更漂亮的方法解决它?

【问题讨论】:

  • 由于date是字符串共振峰,比较Date,应该是Object形式,所以我觉得没有办法不创建更多的DateObject,排序吧。
  • 你的日期字符串是什么格式的?如果它们在 ISO 8601 中,您可以直接比较字符串并获得与比较日期相同的结果。
  • @dkb 是的,没错。但是有没有办法在每个 Oder 中只创建一次 Date 对象?我的第二个示例是为每个“比较”调用创建两个日期对象。它不存储对象。每次新日期都在装箱
  • @Sweeper "yyyy-MM-dd HH:mm:ss"。我猜你的解决方案可能会奏效。你怎么看?
  • 是的,虽然它不是 ISO 8601,但这种格式也可以。

标签: java sorting


【解决方案1】:

可以为唯一日期创建 Date 实例 - 使用 Map

final Comparator<Order> sortByDateAsc = new Comparator<Order>() {
    private final Map<String, Date> map = new HashMap<>();

    @Override
    public int compare(Order o1, Order o2) {
        Date d1 = map.computeIfAbsent(o1.getOrderDate(), Date::new);
        Date d2 = map.computeIfAbsent(o2.getOrderDate(), Date::new);
        return d1.compareTo(d2);
    }
};

orders.sort(sortByDateAsc);

【讨论】:

  • 这看起来是一个非常有趣的方法。谢谢。
【解决方案2】:

您提供的方案中的唯一选项是直接比较字符串。因此,基本上将字符串拆分为相应的内容(年、月、日……),然后比较这些值。只要一个值更高,您就可以返回,例如如果a.month &gt; b.month,则不必比较日期等。

但另一方面,这可能比您当前的方法更难看,也不一定性能更高。

更好的方法是调整 JSON 解析。一个 JSON 应该总是被解析成它各自的对应物,而不是保留字符串。因此,将您的解析调整为已经有Date 而不是String,这样就省去了以后在代码中处理数据的麻烦。这就是编组应该做的事情,给您留下一个普通的(例如)JSON 的 Java 表示来使用它,而不必理会它的起源。

【讨论】:

  • 我有一个非常复杂的 json。对象列表的对象对象等等。它还强调结构可能会有所不同。基本上我将这个 json 传递得更远,而实际上并没有对 Object 做太多事情。我唯一需要做的就是按日期排序。所以将它解析为一个对象会有很大的开销。但是感谢 IDea
猜你喜欢
  • 2022-11-15
  • 2021-01-25
  • 2012-06-26
  • 2016-09-27
  • 2017-08-05
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多