Насколько эффективно мы можем получить требуемый вывод из списка в Java? - PullRequest
3 голосов
/ 26 мая 2019
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. В каждом идентификаторе цепи мне нужно получить запись с наибольшим количеством часов, но при наличии дублированных часов, чеммне нужно взять один с отделом электричества.

Результат для вышеупомянутого результата должен быть как ниже:

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с установщиками-получателями этих трех объектов.

 public class Circuit {

        String circuitID;
        int hours;
        String department;
}

Ответы [ 4 ]

3 голосов
/ 26 мая 2019

Сначала напишите пользовательский компаратор, чтобы проверить наибольшие часы и оценить ситуацию с повторяющимися часами, чтобы взять тот с 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.stream().forEach(x -> System.out.println(x.get().getCircuitId() + "  " + x.get().getDepartment() + "\t" + x.get().getHours()));
3 голосов
/ 26 мая 2019

Вы можете сделать это с помощью 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());
2 голосов
/ 26 мая 2019
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, который соответствует требованиям "max hours". Перебирайте элементы списка и обновляйте карту соответствующим образом, чтобы сохранить новые «максимальные часы» Circuit object

1 голос
/ 26 мая 2019

Сначала нужно сгруппировать по 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;
}
...