从csv文件(Java)显示字符串数组中的重复项

时间:2017-09-01 07:35:28

标签: java csv

我的问题是我从csv文件创建了一个数组,现在我必须输出带有重复项的任何值。 该文件的布局为5x9952。它由数据组成:

id,birthday,name,sex, first name

我现在喜欢在每个栏目中显示我的程序(例如姓名)。就好像有两个人同名。但无论我在互联网上发现什么,只会向我显示行的重复(如果名称和名字相同)。 这是我到目前为止所得到的:

package javacvs;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author Tobias
 */
public class main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        String csvFile = "/Users/Tobias/Desktop/PatDaten/123.csv";
        String line = "";
        String cvsSplitBy = ",";

        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {

            while ((line = br.readLine()) != null) {

                // use comma as separator
                String[] patDaten = line.split(cvsSplitBy);


for (int i = 0; i < patDaten.length-1; i++)
        {
            for (int j = i+1; j < patDaten.length; j++)
            {
                if( (patDaten[i].equals(patDaten[j])) && (i != j) )
                {
                    System.out.println("Duplicate Element is : "+patDaten[j]);
                }
            }
        }
                }
            }catch (IOException e) {
            e.printStackTrace();
        }
        }

    }

(我更改了csv的名称,因为它包含机密数据)

4 个答案:

答案 0 :(得分:0)

您正在迭代行而不是迭代列。你需要做的是在列上进行相同的循环。

您可以做的是在单独的数组中累积名称而不是迭代它。我相信你知道要比较的列是什么索引。因此,您需要一个额外的循环来累积要检查重复的列。

答案 1 :(得分:0)

真实存在:停止思考“低级别”。好的OOP是关于创建有用的抽象。

换句话说:您的第一站应该是创建一个有意义的类定义来表示一行的内容,现在让我们将其称为Person类。然后你将你的进一步关注点分开:

  • 你创建了一个除了读取该CSV文件之外别无其他任何操作的类/方法 - 并且每行创建一个Person对象
  • 您创建了一个有意义的数据结构,告诉您重复项

后者可以(例如)某种反向索引。含义:你有Map<String, List<Person>>。在阅读了所有Person对象(可能在一个简单的列表中)之后,您可以这样做:

Map<String, List<Person>> personsByName = new HashMap<>();
for (Person p : persons) {
  List<Person> personsForName = personsByName.get(p.getName());
  if (personsByName == null) {
    personsForName = new ArrayList<>();
    personsByName.put(p.getName(), personsForName);
  }
  personsForName.add(p);
}

在该循环之后,该映射包含表中使用的所有名称 - 并且对于每个名称,您都有相应人员的列表。

答案 2 :(得分:0)

有点不清楚你想要呈现什么,整个记录,还是只有重复的名字。

仅限名称:

String csvFile = "test.csv";

List<String> readAllLines = Files.readAllLines(Paths.get(csvFile));

Set<String> names = new HashSet<>();

readAllLines.stream().map(s -> s.split(",")[2]).forEach(name -> {
    if (!names.add(name)) {
        System.out.println("Duplicate name: " + name);
    }
});

整个记录:

String csvFile = "test.csv";

List<String> readAllLines = Files.readAllLines(Paths.get(csvFile));

Set<String> names = new HashSet<>();
readAllLines.stream().forEach(record -> {
    String name = record.split(",")[2];
    if (!names.add(name)) {
        System.out.println("Duplicate name: " + name + " with record " + record);
    }
});

答案 3 :(得分:0)

你的问题是你的循环嵌套。你所做的是,你读了一行,将它拆分,然后你将这一行的字段相互比较。你甚至不把一行与其他行比较!

首先,您需要一个适用于所有行的数组,以便您可以比较这些行。正如GhostCat在他的回答中建议的那样,你应该使用你自己的类Person,它有五个字段作为属性。但你可以使用第二个数组,所以你可以像亚历山大彼得罗夫在他的回答中所说的那样使用索引。在后一种情况下,您将获得一个二维数组:

String[][] patDaten;

之后,您将读取csv文件的所有行,并为每行创建一个新的Person或一个新的内部数组。

阅读整个文件后,您可以根据需要比较字段。在这里你使用双循环。因此,您将patDaten[i].getName()patDaten[j].getName()或数组patDaten[i][1]patDaten[j][1]进行比较。