Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 根据用户自定义输入按单个或多个属性对集合进行排序_Java_Spring_Sorting_Jpa_Collections - Fatal编程技术网

Java 根据用户自定义输入按单个或多个属性对集合进行排序

Java 根据用户自定义输入按单个或多个属性对集合进行排序,java,spring,sorting,jpa,collections,Java,Spring,Sorting,Jpa,Collections,我有Item对象的集合,类Item如下-> class Item { String id; String brand; Integer price; Date publishedDate; } 现在,我想根据用户输入进行排序。用户可以根据自己的选择进行分类,比如品牌、价格或发布日期,甚至可以使用多个参数。比如品牌和价格或者价格和发布日期 我见过Comparator通过多个参数进行排序,但这也受到限制,并且使用预定义的参数。所以基本上用户可以按任何输入进行排序,排序机制可以在不更

我有Item对象的集合,类Item如下->

class Item {
  String id;
  String brand;
  Integer price;
  Date publishedDate;
}
现在,我想根据用户输入进行排序。用户可以根据自己的选择进行分类,比如品牌、价格或发布日期,甚至可以使用多个参数。比如品牌和价格或者价格和发布日期

我见过Comparator通过多个参数进行排序,但这也受到限制,并且使用预定义的参数。所以基本上用户可以按任何输入进行排序,排序机制可以在不更改任何代码的情况下处理


我得到了一些使用战略设计模式的提示,但无法在这里实现以解决它。

您可以为每个字段的比较器使用静态映射,并在此基础上构建一个组合比较器: 您仍然必须使比较器为空安全,并检查字段名

class Item {
    String id;
    String brand;
    Integer price;
    Date publishedDate;

    public Item(String id, String brand, Integer price, Date publishedDate) {
        super();
        this.id = id;
        this.brand = brand;
        this.price = price;
        this.publishedDate = publishedDate;
    }

    static Map<String, Comparator<Item>> comparatorMap = new HashMap<String, Comparator<Item>>() {
        {
            put("id", new Comparator<Item>() {
                @Override
                public int compare(Item o1, Item o2) {
                    return o1.id.compareTo(o2.id);
                }
            });
            put("brand", new Comparator<Item>() {
                @Override
                public int compare(Item o1, Item o2) {
                    return o1.brand.compareTo(o2.brand);
                }
            });
            put("price", new Comparator<Item>() {
                @Override
                public int compare(Item o1, Item o2) {
                    return o1.price.compareTo(o2.price);
                }
            });
            put("publishedDate", new Comparator<Item>() {
                @Override
                public int compare(Item o1, Item o2) {
                    return o1.publishedDate.compareTo(o2.publishedDate);
                }
            });
        }
    };

    @Override
    public String toString() {
        return "Item [id=" + id + ", brand=" + brand + ", price=" + price + ", publishedDate=" + publishedDate + "]";
    }

    static class ItemComparator implements Comparator<Item> {
        private List<Comparator<Item>> comparators;

        ItemComparator(String... fields) {
            comparators = new ArrayList<>();
            for (String field : fields) {
                comparators.add(comparatorMap.get((field)));
            }
        }

        @Override
        public int compare(Item o1, Item o2) {
            int result = 0;
            for (Comparator comparator : comparators) {
                result = comparator.compare(o1, o2);
                if (result != 0) {
                    return result;
                }
            }
            return result;
        }

    }

    static List<Item> sort(List<Item> list, String... fields) {
        Collections.sort(list, new ItemComparator(fields));
        return list;
    }

    public static void main(String[] args) {
        List<Item> list = new ArrayList<>();
        list.add(new Item("B", "A", 5, new Date()));
        list.add(new Item("A", "B", 7, new Date()));

        sort(list, "id", "price");
        System.out.println(list);
    }
}
类项目{
字符串id;
串品牌;
整数价格;
发布日期;
公共项目(字符串id、字符串品牌、整数价格、发布日期){
超级();
this.id=id;
这个品牌=品牌;
这个价格=价格;
this.publishedDate=publishedDate;
}
静态映射comparatorMap=newHashMap(){
{
put(“id”,新的比较器(){
@凌驾
公共整数比较(项目o1、项目o2){
返回o1.id.compareTo(o2.id);
}
});
put(“品牌”,新比较器(){
@凌驾
公共整数比较(项目o1、项目o2){
返回o1.brand.compareTo(o2.brand);
}
});
看跌期权(“价格”,新比较器(){
@凌驾
公共整数比较(项目o1、项目o2){
返回o1.价格比(o2.价格);
}
});
put(“publishedDate”,新比较器(){
@凌驾
公共整数比较(项目o1、项目o2){
返回o1.publishedDate.compareTo(o2.publishedDate);
}
});
}
};
@凌驾
公共字符串toString(){
return“Item[id=“+id+”,brand=“+brand+”,price=“+price+”,publishedDate=“+publishedDate+”””;
}
静态类ItemComparator实现Comparator{
私人名单比较国;
ItemComparator(字符串…字段){
比较器=新的ArrayList();
用于(字符串字段:字段){
add(comparatorMap.get((字段));
}
}
@凌驾
公共整数比较(项目o1、项目o2){
int结果=0;
for(比较器比较器:比较器){
结果=比较器。比较(o1,o2);
如果(结果!=0){
返回结果;
}
}
返回结果;
}
}
静态列表排序(列表、字符串…字段){
排序(列表、新ItemComparator(字段));
退货清单;
}
公共静态void main(字符串[]args){
列表=新的ArrayList();
添加(新项目(“B”、“A”、5、新日期());
添加(新项目(“A”、“B”、7、新日期());
排序(列表、“id”、“价格”);
系统输出打印项次(列表);
}
}
编辑

使用比较/再比较的版本

当使用反射获取getter时,可以省略映射

class Item {
    String id;
    String brand;
    Integer price;
    Date publishedDate;

    public Item(String id, String brand, Integer price, Date publishedDate) {
        super();
        this.id = id;
        this.brand = brand;
        this.price = price;
        this.publishedDate = publishedDate;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public Date getPublishedDate() {
        return publishedDate;
    }

    public void setPublishedDate(Date publishedDate) {
        this.publishedDate = publishedDate;
    }

    static Map<String, Comparator<Item>> comparatorMap = new HashMap<String, Comparator<Item>>() {
        {
            put("id", Comparator.comparing(Item::getId));
            put("brand", Comparator.comparing(Item::getBrand));
            put("price", Comparator.comparing(Item::getPrice));
            put("publishedDate", Comparator.comparing(Item::getPublishedDate));
        }
    };

    static List<Item> sort(List<Item> list, String... fields) {
        Comparator comparator = null;
        for (String field : fields) {
            comparator = (comparator == null) ?  comparatorMap.get((field))
                : comparator.thenComparing(comparatorMap.get((field)));
        }

        if (comparator != null) {
            Collections.sort(list, comparator);
        }
        return list;
    }

    @Override
    public String toString() {
        return "Item [id=" + id + ", brand=" + brand + ", price=" + price + ", publishedDate=" + publishedDate + "]";
    }

    public static void main(String[] args) {
        List<Item> list = new ArrayList<>();
        list.add(new Item("B", "A", 5, new Date()));
        list.add(new Item("A", "B", 7, new Date()));

        sort(list, "id", "price");
        System.out.println(list);
    }
}
类项目{
字符串id;
串品牌;
整数价格;
发布日期;
公共项目(字符串id、字符串品牌、整数价格、发布日期){
超级();
this.id=id;
这个品牌=品牌;
这个价格=价格;
this.publishedDate=publishedDate;
}
公共字符串getId(){
返回id;
}
公共无效集合id(字符串id){
this.id=id;
}
公共字符串getBrand(){
回归品牌;
}
公共品牌(字符串品牌){
这个品牌=品牌;
}
公共整数getPrice(){
退货价格;
}
公共定价(整数价格){
这个价格=价格;
}
公共日期getPublishedDate(){
返回数据;
}
public void setPublishedDate(日期publishedDate){
this.publishedDate=publishedDate;
}
静态映射comparatorMap=newHashMap(){
{
put(“id”,Comparator.comparing(Item::getId));
放置(“品牌”,比较器。比较(项目::getBrand));
put(“price”,比较器。比较(Item::getPrice));
put(“publishedDate”,Comparator.comparing(Item::getPublishedDate));
}
};
静态列表排序(列表、字符串…字段){
比较器比较器=空;
用于(字符串字段:字段){
comparator=(comparator==null)?comparatorMap.get((字段))
:comparator.ThenComparating(comparatorMap.get((字段));
}
if(比较器!=null){
集合。排序(列表、比较);
}
退货清单;
}
@凌驾
公共字符串toString(){
return“Item[id=“+id+”,brand=“+brand+”,price=“+price+”,publishedDate=“+publishedDate+”””;
}
公共静态void main(字符串[]args){
列表=新的ArrayList();
添加(新项目(“B”、“A”、5、新日期());
添加(新项目(“A”、“B”、7、新日期());
排序(列表、“id”、“价格”);
系统输出打印项次(列表);
}
}

这些数据来自哪里?通过JPA?…或者你可以使用现代Java和
Comparator.comparing()/Thencarison()
@crizzis Tahnks指出了这一点,以前没有使用过。谢谢@Turo在这里帮助我