【问题标题】:JAVA - How to sort a LIST of OBJECT using comparator by comparing muliplte values inside a LISTJAVA - 如何通过比较列表中的多个值来使用比较器对对象列表进行排序
【发布时间】:2012-01-15 17:09:36
【问题描述】:

我对 Java Comparator 有疑问。或者也许你们都有另一个想法来解决这个问题。

我有一个名为 Product 的对象,在 Product Class 下面看起来像:

public class Product(){
   private String productId;
   private List categoryList;

   //...setter and getter for category List
}

然后我有一个产品列表,列表。我想根据产品的类别对列表进行排序:

这里的列表示例:

{
    Product = {
        productId:10000567,
        categoryList: {1002, 1003, 1007}
    },
    Product = {
        productId:10000568,
        categoryList: {1001, 1003, 1007}
    },
    Product = {
        productId:10000569,
        categoryList: {1001, 1004, 1007}
    },
    Product = {
        productId:10000570,
        categoryList: {1004, 1005, 1007}
    }
}

我已经尝试使用比较器,但我只能比较一个值一次。 感谢您的回复。

【问题讨论】:

  • 您要对哪个列表进行排序?产品列表还是类别列表?如果是产品列表,什么决定一个产品是在另一个产品之前还是之后?类别数?最小类别ID?最大类别id,类别id之和?删除常见类别后的最小类别数?...我想你明白我的意思了。
  • 您当前的比较器是什么样的?
  • 对于 p1 类别列表是 {1002, 1003, 1007} 对于 p2 它是 {1001, 1004, 1007} 什么产品应该是第一个,为什么?您想如何比较列表?
  • @RogerLindsjö 我想根据类别列表对产品列表进行排序。其实我已经有了答案。托马斯启发我这样做。但我仍然无法回答,因为我的声誉低于 1000

标签: java list sorting comparator


【解决方案1】:

假设:

  • 您使用的是 Java 8+
  • 您想先按productId 排序,然后按categoryList
  • categoryList 包含 Comparables(例如字符串或整数)
  • categoryLists 应该使用自然排序成对比较(从最重要的对开始)

然后你可以使用这样的东西:

public static void main(String... args) {
    var p1 = new Product("1", List.of(1001, 1003, 1007));
    var p21 = new Product("2", List.of(1002, 1003, 1004));
    var p22 = new Product("2", List.of(1002, 1002, 1003));
    var p23 = new Product("2", List.of(1001, 1002, 1003));
    var p3 = new Product("3", List.of(1001, 1002, 1003));
    var products = new ArrayList<>(List.of(p3, p1, p21, p22, p23));

    Comparator<Product> productIdComparator = Comparator.comparing(product -> product.productId);
    Comparator<Product> combinedComparator = productIdComparator
            .thenComparing(product -> product.categoryList, comparingListElements(3));
    products.sort(combinedComparator);        // result: p1 p21 p22 p23 p3
}

private static <T extends Comparable<? super T>> Comparator<List<T>> comparingListElements(final int listSize) {
    return IntStream.range(0, listSize)
            .mapToObj(index -> Comparator.comparing((List<T> list) -> list.get(index)))
            .reduce(Comparator::thenComparing)
            .orElseThrow();
}

【讨论】:

    【解决方案2】:

    Thomas 启发了我解决这个问题。问题只是因为我根据多个值比较产品。意思是,对象是多对多的关系。

    我做的很简单,就是写一个比较器类来比较产品的类别。关键是对每个类别进行排序。

    ProductCategoryComparator comparator = new ProductCategoryComparator();
    for (int i = 1 ; i < catKeyList.size() ; i++){
       comparator.setCategoryKey((String)catKeyList.get(i));
       Collections.sort(productList, comparator);
    }
    

    希望这个答案可以帮助每个可能有类似问题的人。

    【讨论】:

      【解决方案3】:

      您可以在 Product 中实现 Comparable 并使用 Collections.sort()。您还必须使列表具有可比性,并在 Product.compareTo() 中使用它。

      【讨论】:

        【解决方案4】:

        首先让你的类Product实现Comparable接口,然后实现compareTo(),然后用Collections.sort(myList)对List进行排序;

        public class Product implements Comparable<Product>{
           private String productId;
           private List categoryList;
        
          //...setter and getter for category List
        
           public int compareTo(Product p) {
               //return -1, 0 or 1 based on what you decide makes p to be less than this
           }
        
        }
        
        //sort it
        java.util.Collections.sort(myProductList);
        

        【讨论】:

        • 嗨,托马斯。感谢您的回复。当然,我已经做了比较器类。但是,如果你能看到,它只会比较每个产品类别列表中的一个值。明白我的意思。当您调用此比较器类时,它只会将 product1.categoryList.get(0) 与 product2.categoryList.get(0) 进行比较。同时我需要根据 categoryList 中的所有类别进行排序。
        • 是的,但是您需要编写 compareTo 以根据您的类别列表中包含的内容返回 -1、0 或 1。如果类别列表的内容应该决定您产品的顺序,您必须在 Product 中实现 compareTo() 来做到这一点。您的产品是否应该根据 categoryList 中的内容总和进行排序?是否应该根据第一个类别元素排序,最后一个?
        • 这里的问题是,产品与类别有多对多的关系。一个产品可以有多个类别,一个类别可以有多个产品。
        • 是的,问题是这样的。对象是多对多关系。我已经得到答案了。我试图回答这个问题。谢谢顺便说一句
        【解决方案5】:

        不确定您是否已经尝试过,但您可以覆盖comparable interface 并使用列表中的值进行比较。

        当然,问题是您需要找到一致的比较算法。您能否根据产品所属的类别确定产品是“大”还是“小”?排序需要这种明确的一维决策……

        否则,您可能希望将内容放入数据库并按类别执行操作

        【讨论】:

        • 是的,我已经为这种排序创建了一个比较器类。但是,我猜这是不正确的。因为它只比较每个产品的一个类别。不幸的是,它不能在数据库端完成。
        猜你喜欢
        • 1970-01-01
        • 2018-09-10
        • 2013-02-13
        • 1970-01-01
        • 1970-01-01
        • 2015-02-18
        • 1970-01-01
        • 2013-09-04
        • 2019-05-25
        相关资源
        最近更新 更多