当前位置: 首页 > 知识库问答 >
问题:

Java 8:在大型列表中计算最小值和最大值的最佳方法

宇文和同
2023-03-14

我有下面的代码,其中计算最小和最大订单项目从列表订单并按预期工作。我想知道是否可以进一步重构/改进,使其更优化和高性能地处理数千或订单列表。

我故意不做 Collections.min(itemFrequencyMap.values()) 和 Collections.max(itemFrequencyMap.values()),因为它需要对所有值进行两次迭代,然后再次循环遍历 itemFrequency Map 以查找具有最小值和最大值的条目。

@Data
public class Order {
    private Long id;
    private String created_at, current_total_price, currency;
    Double total_price;     
    private List<Item> items;
}

@Data
public class Item {
private Long product_id;
String title, name, price;
}

@Data
public class ItemFrequency {
private Item item;
Long frequency;
}

public void minMaxItems(List<Order> orders) {       

    ItemFrequency minOrder = null;
    ItemFrequency maxOrder = null;
    Map<Item, Long> itemFrequencyMap = new TreeMap<>();
    orders.stream()
            .map(o -> o.getLine_items())
            .flatMap(List::stream)
            .forEach(Item -> {
                itemFrequencyMap.compute(Item, (k, v) -> v == null ? 1 : v + 1);
            });

    boolean isFirstEntry = true;
    Long max = Long.MIN_VALUE, min = Long.MAX_VALUE;
    for (Map.Entry<Item, Long> itemFrequency : itemFrequencyMap.entrySet()) {
        Item Item = itemFrequency.getKey();
        if (isFirstEntry) {
            max = itemFrequency.getValue();
            min = itemFrequency.getValue();
            isFirstEntry = false;
            continue;
        }
        if (itemFrequency.getValue() > max) {                
            max = itemFrequency.getValue();
            maxOrder = new ItemFrequency(Item,max);
        } else if (itemFrequency.getValue() < min) {                
            min = itemFrequency.getValue();
            minOrder = new ItemFrequency(Item,min);
        }
    }
    
}

共有1个答案

景俊良
2023-03-14

您可以优化代码以在运行时执行最小和最大有序项目计算,即以不同的顺序添加项目。请在下面找到示例代码。使用这种方法,您可以在O(1)恒定时间内检索最小和最大有序项目。

import java.util.HashMap;
import java.util.List;
import java.util.Objects;

public class Test {
    private static HashMap<Item, Long> itemFrequencyMap = new HashMap<>();
    private static ItemFrequency minOrder;
    private static ItemFrequency maxOrder;


   public ItemFrequency getMinOrder() {
       return minOrder;
   }

   public ItemFrequency getMaxOrder() {
       return maxOrder;
   }

   public static class Item {
       private Long product_id;
       String title;
       String name;
       String price;

       @Override
       public boolean equals(Object o) {
           if (this == o) return true;
           if (!(o instanceof Item)) return false;
           Item item = (Item) o;
           return product_id.equals(item.product_id);
       }

       @Override
       public int hashCode() {
           return Objects.hash(product_id);
       }
   }

      public static class Order {
       private Long id;
       private String created_at, current_total_price, currency;
       private Double total_price;
       private List<Item> items;


       public List<Item> getItems() {
           return items;
       }

       public void addItem(Item item) {
           this.items.add(item);
           long frequency = itemFrequencyMap.getOrDefault(item, 0L) + 1;
           itemFrequencyMap.put(item, frequency);
           if (minOrder.frequency > frequency)
               minOrder = new ItemFrequency(item, frequency);

           if (maxOrder.frequency < frequency)
               maxOrder = new ItemFrequency(item, frequency);
       }
   }
   
   public static class ItemFrequency {
       private Item item;
       private Long frequency;
       public ItemFrequency(Item item, Long frequency) {
           this.item = item;
           this.frequency = frequency;
       }
   }
  }
 类似资料:
  • 这个问题可能是封闭的,因为它听起来很模糊,但我真的问这个,因为我不知道或者我的数学背景不够。 我试图实现一个挑战,其中一部分挑战要求我计算矩阵的最小值和最大值。我对矩阵的实现及其操作没有任何问题,但是什么是矩阵的最小值和最大值?考虑到3x3矩阵是9个数中最小的数,最大的是最大的还是其他什么?

  • 问题内容: 是否可以做这样的事情 要么 在CSS中? 问题答案: ,和终于可以! 从Firefox 75,Chrome 79和Safari 11.1(除外)开始。 并接受任意数量的参数。 具有语法,等效于。 并且可以嵌套。它们既可以在内部使用,也可以在外部使用,它们还可以包含数学表达式,这意味着您可以避免使用它们。 因此,原始示例可以写成:

  • 问题内容: 我有以下格式的多维列表: 如何获得所有子列表的第三个值的最大值。用伪代码: 我知道这可以通过遍历列表并将第三个值提取到新列表中,然后简单地执行来完成,但是我想知道是否可以使用lambda或列表理解来完成? 问题答案: 只需与生成器表达式一起使用: 另外,不要命名您的变量,而是要隐藏类型。

  • 我有这样的课: 和类似的列表,其中填充了元素。 如何使用Java8获得的最小值和最大值?

  • 我试图找出在Spark dataframe列中获得最大值的最佳方法。 考虑以下示例: 上面的每一个都给出了正确的答案,但在没有Spark分析工具的情况下,我无法判断哪一个是最好的。 就Spark运行时或资源使用而言,上述哪种方法最有效,或者是否有比上述方法更直接的方法,有任何来自直觉或经验主义的想法?