我们如何有效地从Java列表中获取所需的输出?

时间:2019-05-26 09:23:39

标签: java list collections java-8

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设置方法。

 public class Circuit {

        String circuitID;
        int hours;
        String department;
}

4 个答案:

答案 0 :(得分:3)

您可以由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());

答案 1 :(得分:3)

首先编写一个自定义比较器,以检查最高时数并评估重复时数的情况,以便与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的{​​{1}}属性进行分组,并借助Collectors.groupingBy(Circuit::getCircuitId,上方的自定义比较器查找最大时数:

Collectors.maxBy(cmp)

答案 2 :(得分:2)

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对象

答案 3 :(得分:1)

我们必须先按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;
}