2016-11-07 83 views
0

我有以下Supplier类型的对象列表,我想用reverseOrder()方法对它们进行排序(所以它们将按降序排列)。但是,在互联网上阅读整整一天后,我仍然无法实现这一目标。我敢肯定,这是我在这里失踪的真正小事。按升序排列的自然顺序工作得很好。使用reverseOrder()与自定义比较器以降序排序列表?

这里是我Supplier类:

public class Supplier { 
    private String supplierName = ""; 
    private String representative = ""; 
    private String representativesPhoneNumber = ""; 

    private Map<Drug, Integer> listOfDrugs = new HashMap<Drug, Integer>(); 

    Supplier(String n, String rep, String repPhoneNum, String drugName, double drugPrice, int stock) { 
     this.supplierName = n; 
     this.representative = rep; 
     this.representativesPhoneNumber = repPhoneNum; 
     listOfDrugs.put(new Drug(drugName, drugPrice), stock); 
    } 

    public Map<Drug, Integer> getListOfDrugs() { 
     return this.listOfDrugs; 
    } 

    public static Integer getKeyExtractor(Supplier supplier, Drug drug) { 
     return Optional.ofNullable(Optional.ofNullable(supplier.getListOfDrugs()) 
            .orElseThrow(() -> new IllegalArgumentException("drugs is null")).get(drug)) 
         .orElseThrow(() -> new IllegalArgumentException("the drug couldn't be found")); 
    } 
} 

它有一个Map如果对象<Drug, Integer>。 这里是我Drug类:

public class Drug { 
    private String name = ""; 
    private double price = 0.0; 

    Drug(String n, double p) { 
     this.name = n; 
     this.price = p; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     long temp; 
     temp = Double.doubleToLongBits(price); 
     result = prime * result + (int) (temp^(temp >>> 32)); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Drug other = (Drug) obj; 
     if (name == null) { 
      if (other.name != null) 
       return false; 
     } else if (!name.equals(other.name)) 
      return false; 
     if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price)) 
      return false; 
     return true; 
    } 
} 

大部分代码是修剪,垃圾邮件的缘故。 :)

而且我Orders班,在那里我居然做了排序:

public class Orders { 
    private Map <Drug, Integer> orderedDrugs = new HashMap <Drug, Integer>(); 
    private Vector<Supplier> suppliers = new Vector <Supplier>(); 

    public void sort(Drug drug, List<Supplier> sortedSuppliers) { 
     Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder())); 
    } 

    public List<Supplier> getSortedSuppliersByQuantity(Drug drug) { 
     List <Supplier> sortedSuppliers = new ArrayList <Supplier>(); 
     for(Supplier s : suppliers) { 
      for(Entry<Drug, Integer> entry : s.getListOfDrugs().entrySet()) { 
       if(entry.getKey().getDrugsName().equals(drug.getDrugsName())); 
        sortedSuppliers.add(s); 
      } 
     } 
     sort(drug, sortedSuppliers); 
     return sortedSuppliers; 
    } 
} 

的代码重新修整,只显示为实际问题所需要的方法。

所以我到目前为止已经有尝试:

  1. Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug), Comparator.reverseOrder()));

  2. Collections.sort(suppliers, Collections.reverseOrder(Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug))));

但两者不工作。我需要在某个地方实施compareTo()还是我缺少某种方法?由于升序工作,但不下降。

Collections.sort(suppliers, Comparator.comparing(s -> Supplier.getKeyExtractor(s, drug)));一起按升序排列并工作。

非常感谢您的帮助,对于这篇长文章感到抱歉!

UPDATE:

我也试图在Supplier类来实现compareTo,但我得到一个NPE。 :/

public int compareTo(Supplier a) { 
    for(Entry<Drug, Integer> entry : listOfDrugs.entrySet()) { 
     int result = listOfDrugs.get(entry.getKey()).compareTo(a.listOfDrugs.get(entry.getKey())); 
     if(result != 0) 
      return result; 
    } 
    return 0; 
} 
+0

你是什么意思“都不行”? –

+0

@NicolasFilotto,我的意思是,当我尝试使用它们时,我以原始方式得到List - 无序。 – Calihog

+1

请提供一个示例,以便我们轻松复制 –

回答

1

尝试

Collections.sort(suppliers, 
       Comparator.comparing((Supplier s) -> Supplier.getKeyExtractor(s, drug)).reversed()); 

我建了一个简化的版本,这个工作。我没有和你一起尝试Supplier等课程。

+0

Reverse只反转列表。在下面看到我的更新。 –

+1

@RavindraHV'比较器#颠倒'与任何列表无关。 [阅读javadocs](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#reversed--) - 它返回一个比较器,强制该比较器的反向排序。 – bradimus

+0

感谢您的帮助@bradimus,但它不适合我。 :(我得到和原来一样的列表 – Calihog

-2

是的,你需要。执行Comparator(并根据需要对其进行调整),并调用sort方法。

更新: 要使用lambda表达式进行操作,请尝试使用here

更新#2:

下面是我想出了。希望它能帮助:

/** 
Input:[9, 9, 5, 1, 6, 3, 9, 4, 7, 1] 
Reversed:[1, 7, 4, 9, 3, 6, 1, 5, 9, 9] 
ReverseOrdered:[9, 9, 9, 7, 6, 5, 4, 3, 1, 1] 
    */ 
    private static void testCollectionsSort() { 

     List<Integer> integerList = new ArrayList<>(); 
     int size=10; 
     Random random = new Random(); 
     for(int i=0;i<size;i++) { 
      integerList.add(random.nextInt(size)); 
     } 

     System.out.println("Input:"+integerList); 
     List<Integer> integerListTwo = new ArrayList<>(integerList); 
     Collections.reverse(integerListTwo); 
     System.out.println("Reversed:"+integerListTwo); 
     Comparator<Integer> integerComparator = (Integer a, Integer b) -> b.compareTo(a); // 'b' is compared to 'a' to enable reverse 
     Collections.sort(integerList, integerComparator); 

     System.out.println("ReverseOrdered:"+integerList); 
    } 
+0

对于可能看起来没有问题的东西我很抱歉,但我认为'Comparator.comparing(s - > Supplier .getKeyExtractor(s,drug),Comparator.reverseOrder())'实际上是Java-8语法中的比较器吗? – Calihog

+0

已使用新链接更新答案。反向排序反转列表。它与降序排序不同。我是lambda新手,但我可以告诉你的是,你需要实现compare-to并定制逻辑 - 更大,更等,更小。 –

+0

更新:颠倒订单**确实会颠倒订单!我正在查看[reverse-list](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#reverse-java.util.List-)。 –

0

好的,我找到了一个解决问题的办法,因为一切都不适合我。在按升序对列表进行排序后,使用sort方法,我只需调用:Collections.reverse(myList);,然后按降序获取排序列表。我知道这可能是蹩脚的,但它适用于我。