Суммируйте каждый столбец списка и добавьте его к последним элементам

У меня есть данные, как показано ниже:

 List<T> mainList = {
    { ID = 001, Name = "AAA", List<String>totalTimeList = {"8", "0.45", "2"},
    { ID = 002, Name = "BBB", List<String>totalTimeList = {"10", "1.3", "2.2"},
    { ID = 003, Name = "CCC", List<String>totalTimeList = {"9", "1.3", "2.4"}
 }

Примечание. totalTimeList - список часов и минут. (1,3 = 1 час 30 минут.)
Как добавить последний элемент в «mainList» для суммирования каждого столбца «totalTimeList»?
Результат вывода:

 List<T> mainList = {
         { ID = 001, Name = "AAA", List<String>totalTimeList = {"8", "0.45", "2"},
         { ID = 002, Name = "BBB", List<String>totalTimeList = {"10", "1.3", "2.2"},
         { ID = 003, Name = "CCC", List<String>totalTimeList = {"9", "1.3", "2.4"},
         { ID = null, Name = null, List<String>totalTimeList = {"27", "3.45", "7"}
    }

Можно ли для этого использовать поток Java?

Вот мой код:

List<T> mainList = {
        { ID = 001, Name = "AAA", List<String>totalTimeList = {"8", "0.45", "2"},
        { ID = 002, Name = "BBB", List<String>totalTimeList = {"10", "1.3", "2.2"},
        { ID = 003, Name = "CCC", List<String>totalTimeList = {"9", "1.3", "2.4"}
     }
int sizeOftotalTimeList = mainList[0].getTotalTimeList.size();
List<String> lstSum = new ArrayList<>(Collections.nCopies(sizeOftotalTimeList , "0"));                          

for (T tmp: mainList ) {
  List<String> lstHr = tmp.getTotalTimeList();    
  for (int i = 0; i < lstHr.size(); i++) {
    int allMinute = 0;
    if(lstSum.size() > 0 && lstSum.size()-1 >= i) {
       Double sumOld = Double.valueOf(lstSum.get(i));                                        
       String[] part = String.format ("%.2f", sumOld).split("\\.");                                      
       allMinute = (Integer.parseInt(part[0])*60) + Integer.parseInt(part[1]);                                   
    }   
    Double number = Double.valueOf(lstHr.get(i));
    String[] separated = String.format ("%.2f", number).split("\\.");
    allMinute += (Integer.parseInt(separated[0])*60) + Integer.parseInt(separated[1]);  
    lstSum.set(i, convertToHoursMinutes(allMinute));
  }                             
}

T lastT = new T();
lastT.setTotalTimeList(lstSum);
mainList.add(lastT);

Пожалуйста, опубликуйте код, который вы пробовали. По крайней мере, покажите, как вы решили это с помощью традиционных циклов.

Kartik 26.10.2018 06:37

Я добавил код на свой вопрос. Пожалуйста, предложите мне.

Java beginer 26.10.2018 11:00
3
2
64
1

Ответы 1

Сделать это можно так: -

List<Student> mainList = getMainList();
List<Double> newTimeList = Stream.of(0.0, 0.0, 0.0).collect(Collectors.toCollection(ArrayList::new));
List<Double> totalTimeLists = mainList.stream()
        .flatMap(student -> student.getTotalTimeList().stream())
        .map(Double::parseDouble)
        .collect(Collectors.toCollection(ArrayList::new));
for (int i = 0; i < totalTimeLists.size(); i++) {
    int pos = i % 3;
    //TODO apply mod if sum is greater than 59
    newTimeList.set(pos, newTimeList.get(pos) + totalTimeLists.get(i));
}
mainList.add(new Student(0, null,
        newTimeList.stream()
                .map(String::valueOf)
                .collect(Collectors.toCollection(ArrayList::new))));

Я мог бы преобразовать приведенный выше цикл for в цикл типа диапазона IntStream, но это не рекомендуется. Читаемость важнее, чем пытаться все изменить в стиле Stream / лямбда / функциональность.

Я использовал класс Student для хранения идентификатора, имени, списка времени: -

public class Student {
    private int id;
    private String name;
    private List<String> totalTimeList;

    //constructor, getters/setters
}

PS - Я использовал toCollection(ArrayList::new) вместо toList(), потому что здесь очень важен порядок списков, а toList() не гарантирует, какой тип списка будет возвращен.

Другие вопросы по теме