Java 根据Map的值对 List<Map<String, Object>> 进行排序

对 List<Map<String, Object>> 类型数据的排序

有一个Map列表, 需要对这个列表, 按Map的某几个value进行排序, 并且还要分别指定正序或者倒序. 这个实现在数据库中是非常简单的, 一串 order by col1 asc, col2 desc 搞定, 但是在Java中, 就会比较啰嗦.
记录一下, 在对比两个具体值的时候, 区分类型实现的compare方法.

/**
 * 对List&lt;Map&gt;排序, 基于多个键
 * @param sorts 排序字段和方向列表
 * @return 排序后的列表
 */
private Comparator<Map<String, Object>> mapComparator(List<Pager.Sort> sorts) {
    return (o1, o2) -> {
        int ret = 0;
        for (Pager.Sort sort : sorts) {
            Object v1 = o1.get(sort.field);
            Object v2 = o2.get(sort.field);
            ret = singleCompare(v1, v2, sort.order == Pager.Order.ASC);
            if (ret != 0) {
                break;
            }
        }
        return ret;
    };
}

private int singleCompare(Object av, Object bv, boolean asc) {
    int ret;
    if (av == null && bv == null) {
        ret = 0;
    } else if (av == null) {
        ret = -1;
    } else if (bv == null) {
        ret = 1;
    } else  if (av instanceof BigDecimal) {
        ret = ((BigDecimal)av).compareTo((BigDecimal)bv);
    } else if (av instanceof Number) {
        if (((Number)av).doubleValue() != ((Number)bv).doubleValue()) {
            ret = ((Number)av).doubleValue() > ((Number)bv).doubleValue()? 1 : -1;
        } else {
            ret = 0;
        }
    } else if (av instanceof Date) {
        ret = ((Date)av).compareTo((Date)bv);
    } else {
        ret = String.valueOf(av).compareTo(String.valueOf(bv));
    }
    if (!asc) {
        return -ret;
    }
    return ret;
}

调用

List<Map<String, Object>> sorted = list.stream()
                .sorted(mapComparator(pager.getSorts()))
                .collect(Collectors.toList());

在 singleCompare 这个方法中, 要注意大于, 等于, 小于三种情况都要明确判断, 不能漏, 否则在sorted中会出现"Comparison method violates its general contract!"错误.

对 List 类型数据的排序

使用 Collections.sort()

private static void order(List<UserPO.Field> fields) {
    Collections.sort(fields, new Comparator<UserPO.Field>() {
        public int compare(UserPO.Field o1, UserPO.Field o2) {
            int ret = o1.getKey().compareTo(o2.getKey());
            if (ret != 0) {
                return ret;
            }
            ret = o1.getType().compareTo(o2.getType());
            if (ret != 0) {
                return ret;
            }
            // ...

            return o1.getName().compareTo(o2.getName());
        }
    });
}

posted on 2022-08-25 17:58  Milton  阅读(863)  评论(0编辑  收藏  举报

导航