将 ArrayList<Object> 与 List<String> 进行比较,然后执行一些计算并打印出结果

时间:2021-04-09 14:55:28

标签: java list

我有以下 List<Client>,其中名称重复且不按顺序以及持续时间(以秒为单位):

  1. 名称 1 , 100
  2. 姓名 2 , 15
  3. 姓名 3 , 45
  4. 姓名 1 , 30
  5. 姓名 3 , 12
  6. 姓名 2 , 22

此列表是从 CSV 文件中读取的,名称一直在变化。

我需要把每个名字的持续时间加起来,然后用下面的方式打印出来:

  • 姓名 1 ,总时长:130
  • 姓名 2 ,总时长:37
  • 姓名 3,总时长:57

此列表有 1000 多个条目。

请帮忙,因为我无法解决这个问题。

我从 List<String> 中提取了一个 List<Client>,删除了重复项。留给我以下内容:

  • 姓名 1
  • 姓名 2
  • 姓名 3

然而,我在这之后迷路了。

2 个答案:

答案 0 :(得分:2)

您可以为此使用 Java 流,就像这样('rl' 将是包含合并条目的结果列表。'l' 是源列表):

List<Entry> rl = new ArrayList<>(
         l.stream()
         .collect(Collectors.toMap(
                 Entry::getName,
                 e -> e,
                 Entry::merge
         )).values()
);

或者如果你想要一个排序的结果:

List<Entry> rl = l.stream()
                  .collect(Collectors.toMap(
                          Entry::getName,
                          e -> e,
                          Entry::merge
                  ))
                  .values()
                  .stream()
                  .sorted(Comparator.comparing(Entry::getName))
                  .collect(Collectors.toList());

我正在使用以下数据结构(用你的替换它):

public static class Entry {
    public String name;
    public long duration;

    public Entry(String name, long duration) {
        this.name = name;
        this.duration = duration;
    }

    public String getName() {
        return name;
    }

    public long getDuration() {
        return duration;
    }

    @Override
    public String toString() {
        return "Name: " + name + ", Total Duration: " + duration;
    }

    public static Entry merge(Entry e1, Entry e2) {
        return new Entry(e1.getName(), e1.getDuration() + e2.getDuration());
    }
}

答案 1 :(得分:0)

您应该使用地图而不是列表作为结果数据结构。迭代您的列表,以逗号分隔,使用名称作为键,使用持续时间作为值。在插入地图之前检查键是否已经存在,如果存在则更新值如果不插入它。下面是一个让您入门的简单示例:

假设您有一个类似于以下内容的 csv 文件:

John, 100
Sarah, 15
Alex, 45
John, 30
Sarah, 12
Alex, 22

代码:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Example {

    public static void main(String args[]) throws IOException {
        //path to your file, eg. C:\\Users\\Rid00\\Documents\\myfile.csv
        String pathToFile = "path to file";
        List<String> fileContent = readCsvFile(pathToFile);
        Map<String,Integer> durationPerName = getTotalDurations(fileContent);

        //do whatever with your result, for example print it to console
        for(Map.Entry<String,Integer> entry : durationPerName.entrySet()){
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
    }

    public static List<String> readCsvFile(String fileName) throws IOException {
        //read all lines of csv file to a list
        Path path = Paths.get(fileName);
        List<String> allLines = Files.readAllLines(path);
        return allLines;
    }

    public static Map<String,Integer> getTotalDurations(List<String> linesFromFile){
        Map<String,Integer> result = new HashMap<>();
        for(String line : linesFromFile){
            //split at comma and remove extra spaces before and/or after the delimiter
            String[] splited = line.split("\\s*,\\s*");
            String name = splited[0];
            int duration = Integer.parseInt(splited[1]);

            //check if map doesn't contains key, if no insert it
            if(!result.containsKey(name)){
                result.put(name, duration);
            }
            //else if map already contains key, get the value and add the current duration to it
            else{
                result.put(name, result.get(name) + duration);
            }
        }
        return result;
    }
}