【问题标题】:Arranging values of an arrayList in a specifed order using java使用java以特定顺序排列arrayList的值
【发布时间】:2013-02-16 18:45:07
【问题描述】:

我试图为以下场景找到更好和优化的解决方案
我有一个数组列表

ArrayList<Order> orders = new ArrayList<Order>();  

排序后的结果值如下

    {  
     medicine,    
     medicine,  
     milk,    
     milk,    
     pillow,  
     Soap,         
     toy       
}  

我对所有这些项目都有一个枚举

public Enum Items{  
PILLOW("pillow"),  
HARDDISK("harddisk"),  
MILK("milk"),  
SOAP("soap"),  
MEDICINE("medicine"),  
TOY("toy")    
}

我的输出顺序应该如下

{    
milk,  
milk,  
harddisk,  
medicine,  
medicine,  
toy,  
soap,  
pillow  
}  

为了完成这一切,我想做的就是

ArrayList<Order> resultList = new ArrayList<Order>();  
for(Order order: orders){  
if(order.getItemName.equals(Items.MILK){  
resultList.add(order);  
}    

for(Order order: orders){    
if(order.getItemName.equals(Items.MEDICINE){  
resultList.add(order);    
}  

.......  

for(Order order: orders){  
if(order.getItemName.equals(Items.PILLOW){  
resultList.add(order);  
}  

如果我遵循上述方法,我能够以上述指定顺序获得输出顺序,但我担心的是因为我在这里循环了许多 for 循环,我想要优化方法的建议。

输出应按以下顺序排序

1) 牛奶 2) 硬盘 3) 医学 4) 玩具 5) 肥皂 6) 枕头

【问题讨论】:

  • 你为什么会期待这个输出?这不是自然排序。您要在什么基础上进行排序?
  • 这个答案解决了带有自定义比较器的枚举:stackoverflow.com/a/519844/1598965

标签: java arraylist


【解决方案1】:

您可以使用 Collections#sort(list,comparator) 代替它,您可以在其中传递自定义比较器以按特定顺序获取结果。

Collections.sort(list, new Comparator<Order>() {

    @Override
    public int compare(Order obj1, Order obj2) {
         // write the custom logic 
         // a negative integer, zero, or a positive integer as the first argument
         // is less than, equal to, or greater than the second
         return 0;
    }
});

【讨论】:

  • 我很欣赏上述方法,但我已经有按升序排序的数组列表。我想要的只是按自定义排序顺序输出结果,即 1)牛奶 2)硬盘 3)药品 4)玩具 5)肥皂 6)枕头
  • 我们使用Comparator来获得定制订单。我们可以编写自定义逻辑来获取订单。
  • 我在列表中也有重复值
【解决方案2】:

枚举具有自然顺序,即枚举成员的声明顺序。所以如果你想要你指定的顺序,枚举应该声明为:

public Enum Item {  
    MILK("milk"),  
    HARDDISK("harddisk"),  
    MEDICINE("medicine"),  
    TOY("toy"),
    SOAP("soap"),  
    PILLOW("pillow");    
}

然后您可以像这样对订单进行排序:

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

如果不能修改枚举,则使用以下技巧:

private static final List<Item> ITEMS_IN_ORDER = Arrays.asList(new Item[] {
    Item.MILK,  
    Item.HARDDISK,  
    Item.MEDICINE,  
    Item.TOY,
    Item.SOAP,  
    Item.PILLOW
});

...

Collections.sort(orders, new Comparator<Order>() {
    @Override
    public int compare(Order o1, Order o2) {
        return Integer.compare(ITEMS_IN_ORDER.indexOf(o1.getItem()),
                               ITEMS_IN_ORDER.indexOf(o2.getItem()));
    }
});

【讨论】:

  • 我很感激,但在我的场景中,这个枚举是通用的,我的意思是它也用于其他模块,我不能让它适用于一个模块
【解决方案3】:

另一种选择,将您的枚举类修改为

public Enum Items{ 
 MILK("milk",1),     
 HARDDISK("harddisk",2),
 MEDICINE("medicine",3),  
 TOY("toy",4)  
 SOAP("soap",5),  
 PILLOW("pillow",6), 

 private String name;
 private sortValue;


Items(double name, double sortValue) {
    this.name= name;
    this.sortValue= sortValue;
} 
}

使用比较器,根据排序值进行排序

Collections.sort(list,new Comparator<Fruit>() {

        public int compare(Items item1, Items item2) {
                   return item1.sortValue - item2.sortValue;

});

与 JB Nizet 相比,它的一个优势是它不依赖于您在 Enum 类中声明值的顺序

【讨论】:

  • 好..但约束是我正在使用其他人的 jar 文件...我不应该对他们现有的代码进行任何更改...我只想更好地实现事情我的身边
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多