【问题标题】:How efficiently we can get the required output from the list in java?我们如何有效地从 java 中的列表中获取所需的输出?
【发布时间】:2019-10-12 05:07:32
【问题描述】:
CircuitID   Department  Hours

--------------------------------

Circuit A   Electricity      60

Circuit A   Hydel            70

Circuit B   Hydel            30

Circuit C   Electricity      40

Circuit B   Electricity      80

Circuit C   Hydel            50

Circuit A   Electricity      70

现在我必须创建一个包含以下条件记录的列表:

  1. 在每个电路 ID 中,我需要获取最高小时数的记录,但如果存在重复的小时数,我需要使用电力部门的记录。

上述结果的结果应如下所示:

Circuit A  Electricity   70

Circuit B  Electricity   80

Circuit C  Hydel          50

让我知道如何使用 java 8/java 以最有效的方式进行有效迭代以获取最终列表。

我写的代码一点也不完美,我的方法如下所示:

for (int i = 0; i < circuitList.size(); i++) {

  for (int j = 0; j < circuitList.size(); {
    if (circuitList.get(i).getCircuitId().equals(circuitList.get(j).getCircuitId()) && i != j) {



     if (circuitList().get(i).getHours() == circuitList().get(j).getHours()) {



      if (circuitList().get(i).getDepartment().equals(“Electricity”) {



        newList.add(circuitList().get(i));

        }

        // some more conditions on getHours

Circuit 类的 pojo 对象具有这三个对象的 getter setter。

 public class Circuit {

        String circuitID;
        int hours;
        String department;
}

【问题讨论】:

  • 请展示Circuit 类的样子。此外,如果您更正诸如 getCircuitIdgetCircuitId()“Electricity”circuitList() 之类的拼写错误以及缩进和右大括号,那就太好了
  • 按电路使用groupingBycollect。使用maxBy 的下游,收集器先按小时排序,然后按类型排序。

标签: java list collections java-8


【解决方案1】:

首先编写一个自定义比较器来检查最高小时数并评估重复小时数情况以采用Electricity 部门:

Comparator<Circuit> cmp = new Comparator<Circuit>() {
    @Override
    public int compare(Circuit o1, Circuit o2) {
        
        int compare = Integer.compare(o1.getHours(), o2.getHours());
        
        if(compare==0) {  // equal hours so check for department

            // the element with 'Electricity' value must seem to be have max value
            if(o1.getDepartment().equals("Electricity")) {
                compare = 1;
            }
            if(o2.getDepartment().equals("Electricity")) {
                compare = -1;
            }
        }
        
        return compare;
    }
};

然后将circuitId 属性与Collectors.groupingBy(Circuit::getCircuitId, 分组,并在Collectors.maxBy(cmp) 上方的自定义比较器的帮助下找到最大小时数:

Map<String, Optional<Circuit>> resultMap = circuitList.stream().collect(
                Collectors.groupingBy(Circuit::getCircuitId, Collectors.maxBy(cmp)));
Collection<Optional<Circuit>> result = resultMap.values();
result.forEach(x -> System.out.println(x.get().getCircuitId() + "  " + x.get().getDepartment() + "\t" + x.get().getHours()));

【讨论】:

    【解决方案2】:

    您可以通过 toMap() 具有合并功能的收藏家来完成。

    Map<String, Circuit> map = circuitList
                 .stream()
                 .collect(Collectors.toMap(Circuit::getCircuitID, Function.identity(),merge));
    

    合并函数为:

    BinaryOperator<Circuit> merge = (left, right) -> {
            if (left.hours > right.hours) return left;
            else if (left.hours < right.hours) return right;
            //if (left.department.equals("Electricity")) return left;
            if (right.department.equals("Electricity")) return right;
            return left;
    };
    

    并得到最终结果:

    List<Circuit> result = new ArrayList<>(map.values());
    

    【讨论】:

    • 您可以完全删除if (left.department.equals("Electricity")) return left; 检查。
    • 为什么不只是maxBy
    • @BoristheSpider,是的,我也想过。 Comparator&lt;Circuit&gt; comparator = Comparator.comparing(Circuit::getHours) .thenComparingInt(circuit -&gt; circuit.circuitID.equals("Electricity")?1:-1); 然后Map&lt;String, Optional&lt;Circuit&gt;&gt; map = circuitList .stream() .collect(Collectors.groupingBy(Circuit::getCircuitID,Collectors.maxBy(comparator)));
    • 你的比较器是错误的,因为它永远不会返回 0 - 但是,是的,类似的东西。
    • @Joka Lee result.forEach(circuit-&gt;System.out.printLn("[CircuitID: "+circuit.circuitID+ " Department :" + circuit.department + " Hours : "+ circuit.hours +"]"));
    【解决方案3】:

    我们必须先按 CircuitID 分组,然后根据我们的要求编写自定义比较器进行过滤。可以如下图完成:

    List<Circuits> filteredList = new ArrayList<>();
    list.stream().collect(Collectors.groupingBy(Circuits::getCircuitID)).forEach((key, value) -> filteredList.add(compare(value)));
    
    
    private static Circuits compare (List<Circuits> list) {
        Circuits circuits = null;
        for (Circuits c : list) {
            if (null == circuits) {
                circuits = c;
            }
            if (c.getHours() > circuits.getHours()) {
                circuits = c;
            } else if (c.getHours() == circuits.getHours()) {
                circuits = c.getDepartment().equalsIgnoreCase("Electricity") ? c : circuits;
            }
        }
        return circuits;
    }
    

    【讨论】:

      【解决方案4】:
      public static Map<String, Circuit> getMaxHours(final List<Circuit> circuitsList) {
          final Map<String, Circuit> mappedCircuitsById = new HashMap<String, Circuit>();
      
          for (final Circuit circuit : circuitsList) {
              if (!mappedCircuitsById.containsKey(circuit.getCircuitID())) {
                  mappedCircuitsById.put(circuit.getCircuitID(), circuit);
              } else {
                  final Circuit existingMax = mappedCircuitsById.get(circuit.getCircuitID());
                  if (circuit.getHours() > existingMax.getHours()) mappedCircuitsById.put(circuit.getCircuitID(), circuit);
                  else if (circuit.getHours() == existingMax.getHours()) {
                      if (circuit.getDepartment().equals("Electricity")) mappedCircuitsById.put(circuit.getCircuitID(), circuit);
                      else if (existingMax.getDepartment().equals("Electricity")) mappedCircuitsById.put(circuit.getCircuitID(), existingMax);
                  }
              }
          }
      
          return mappedCircuitsById;
      }
      

      创建一个映射,其中映射的键是circuitID,值是满足“最大小时数”要求的Circuit 对象。遍历列表的元素并相应地更新地图以存储新的“最大小时数”Circuit 对象

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-15
        • 2016-03-13
        • 1970-01-01
        • 2016-02-17
        相关资源
        最近更新 更多