【问题标题】:Show duplicates in a String Array from csv File (Java)显示来自 csv 文件的字符串数组中的重复项(Java)
【发布时间】:2017-09-01 07:35:28
【问题描述】:

我的问题是我从 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 的名称,因为它包含机密数据)

【问题讨论】:

    标签: java csv


    【解决方案1】:

    这里的真实情况:停止思考“低级”。好的 OOP 是关于创建有用的抽象。

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

    • 您创建了一个类/方法,除了读取该 CSV 文件之外什么都不做 - 并且每行创建一个 Person 对象
    • 您创建了一个有意义的数据结构来告诉您重复项

    后者可以(例如)某种反向索引。含义:你有一个Map&lt;String, List&lt;Person&gt;&gt;。在阅读完所有 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】:

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

      您可以做的是将名称累积到一个单独的数组中,然后对其进行迭代。我确定您知道要比较的列是什么索引。因此,您将需要一个额外的循环来累积要检查重复的列。

      【讨论】:

        【解决方案3】:

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

        仅供参考:

        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);
            }
        });
        

        【讨论】:

        • 谢谢,第二个正是我想要的。现在出现的唯一问题是循环不会自行停止,我不知道如何解决。
        • @TobiasL 根据this answer Stream.forEach 不是循环,也不是为使用break 之类的东西终止而设计的。所以你必须使用你的循环。
        【解决方案4】:

        您的问题是循环的嵌套。您所做的是,您阅读一行,将其拆分,然后将这一行的字段相互比较。你甚至没有将一行与其他行进行比较!

        因此,首先您需要一个包含所有行的数组,以便您可以比较这些行。正如 GhostCat 在他的回答中建议的那样,您应该使用您自己的类 Person,它具有五个字段作为属性。但是您可以使用第二个数组,这样您就可以使用 Alexander Petrov 在他的回答中所说的索引。在后一种情况下,您会得到一个二维数组:

        String[][] patDaten;
        

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-01-17
          • 2017-08-07
          • 2015-02-14
          • 1970-01-01
          • 1970-01-01
          • 2014-07-29
          • 2015-06-10
          相关资源
          最近更新 更多