【问题标题】:Reducing Code Duplication with For loop in java使用 Java 中的 For 循环减少代码重复
【发布时间】:2021-07-19 20:36:45
【问题描述】:
    for (Aircraft aircraft : landingQueue) {
        if (aircraft.hasEmergency()) {
            return aircraft;
        }
    }

    for (Aircraft aircraft : landingQueue) {
        if (aircraft.getFuelPercentRemaining() <= 20) {
            return aircraft;
        }
    }

    for (Aircraft aircraft : landingQueue) {
        if (aircraft instanceof PassengerAircraft) {
            return aircraft;
        }
    }
    return landingQueue.get(0);

所以我的程序运行队列中的飞机列表,并根据任务的重要性返回一个。例如,它将首先检查landingQueue ArrayList 以查看是否有任何飞机处于紧急状态,如果找不到,则检查燃油少于20 的飞机,依此类推。有没有一种简单的方法可以减少 for 循环和 if 语句的重复?非常感谢

【问题讨论】:

    标签: java for-loop duplicates


    【解决方案1】:

    另一种方法是根据您的优先标准对列表进行排序

    public Aircraft returnOneBasedOnImportance(){
        Comparator<Aircraft> byEmer = Comparator.comparing(a -> !a.hasEmergency());
        Comparator<Aircraft> byFuel = Comparator.comparing(a -> !(a.getFuelPercentRemaining() <= 20));
        Comparator<Aircraft> byType = Comparator.comparing(a -> !(a instanceof PassengerAircraft));
    
        return landingQueue.stream()
                           .sorted(byEmer.thenComparing(byFuel).thenComparing(byType))
                           .findFirst().get();
    }
    

    【讨论】:

      【解决方案2】:

      改进不在于代码重复,更重要的是限制了迭代该列表的次数。

      Aircraft firstEmergencyAircraft = null;
      Aircraft firstLowFuelAircraft = null;
      Aircraft firstPassengerAircraft = null;
      
      for (Aircraft aircraft : landingQueue) {
              if (firstEmergencyAircraft==null && aircraft.hasEmergency()) {
                  firstEmergencyAircraft = aircraft;
              }
              if (firstLowFuelAircraft==null && aircraft.getFuelPercentRemaining() <= 20) {
                  firstLowFuelAircraft = aircraft;
              }
              if (firstPassengerAircraft==null && aircraft instanceof PassengerAircraft) {
                  firstPassengerAircraft = aircraft;
              }
          }
      
      if(firstEmergencyAircraft!=null){
          return firstEmergencyAircraft;
      }
      if(firstLowFuelAircraft!=null){
          return firstLowFuelAircraft;
      }
      if(firstPassengerAircraft!=null){
          return firstPassengerAircraft;
      }
      return landingQueue.get(0);
      

      【讨论】:

        【解决方案3】:

        我会让landingQueue 成为某种SortedSet(即TreeSet),并带有一个按着陆优先级排序的Comparator(即排序标准是紧急情况,低燃料水平,是PassangerAircraft)。然后,您始终可以从列表中选择第一个(或最后一个)条目。

        【讨论】:

          【解决方案4】:

          一种选择是首先创建一个谓词流,然后为每个谓词循环遍历列表并尝试找到匹配的飞机。如果未找到匹配项,则返回第一个元素。

          Stream<Predicate<Aircraft>> predicates = Stream.of(
            (aircraft) -> aircraft.hasEmergency(),
            (aircraft) -> aircraft.getFuelPercentRemaining() <= 20,
            (aircraft) -> aircraft instanceof PassengerAircraft
          );
          
          return predicates
            .flatMap((predicate) -> landingQueue.stream().filter(predicate))
            .findFirst()
            .orElse(landingQueue.get(0));
          

          【讨论】:

            【解决方案5】:

            为什么不只在一个循环中进行测试?

            for (Aircraft aircraft : landingQueue) {
                if (aircraft.hasEmergency() ||
                    aircraft.getFuelPercentRemaining() <= 20 ||
                    aircraft instanceof PassengerAircraft) {
                    return aircraft;
                }
            }
            
            return landingQueue.get(0);
            

            【讨论】:

            • 这不会改变逻辑吗?它应该首先检查是否有任何飞机发生紧急情况,现在它将返回任何符合任何条件的飞机。
            • 像 QBrute 的回答一样改变逻辑
            • 参见 Java 语言规范 (docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.24) 的 en.wikipedia.org/wiki/Short-circuit_evaluation 和 15.24。布尔操作数按顺序求值,会短路。
            • 假设landingQueue中的第二项是一架客机,但没有紧急情况。第五项有应急,但不是客机,所有飞机都有20多个燃料。您的算法将返回队列中的第二项,但 OP 的代码将返回第五项。
            • 我考虑删除我的答案,因为我意识到这是错误的。我把它留在这里是为了帮助其他人看到逻辑错误。我建议每个人都阅读@Eritrean 的答案,因为我认为这是正确且最优雅的。
            猜你喜欢
            • 2021-03-18
            • 1970-01-01
            • 1970-01-01
            • 2023-03-25
            • 1970-01-01
            • 2011-06-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多