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