Side-effects

Stream.forEach() operation should be utilized with care since it operates via side-effects and should not be used as a substitution of a proper reduction operation.

The way you've written this stream is discouraged by the Stream API documentation because it makes code more cluttered and difficult to follow and more importantly your solution is broken with parallel streams (there should be no assumptions on the nature of the stream in your code).

In this particular case, you should be using Stream.toArray() operation instead.

Multiline lambdas

Try to void them. They bear a lot of cognitive load. If a lambda expression requires several lines or when you have a complex single-line lambda (e.g. with a nested stream in it), consider introducing a method.

Exceptions

In short, the purpose of exceptions is to indicate cases when it's not possible to proceed with the normal execution flow.

If you stumbled on a corrupt piece of data which violates invariant that are important for your business logic, usually you don't want to proceed processing it. That's a valid case to throw. You asked can you "throw from a stream"? Sure, it's just a means iteration.

I've seen some bickering over whether it's appropriate to use exceptions for the purpose of validation. Sure it is, we do employ Exceptions for Validation for decades.

Unless you're using exceptions to avoid conditional logic, or to make weird hacks like throwing in order to break from a recursive method, and you have a genuine invalid piece of data on your hands you can and should throw.

Another, important note: exceptions should be informative. If standard exception types can describe the case at hand, fine, if not introduce your own exception type.

Also, use proper exception messages that will be helpful in investigating the issue.

Static routines

Don't treat everything as util classes, use the Power of object-orientation to make more clean, cohesive and testable.

Refactored version

public class ArrayParser {
    private final String separator;
    private final int columnCount;
    
    public ArrayParser(String separator, int columnCount) {
        this.separator = separator;
        this.columnCount = columnCount;
    }
    
    public String[][] parse(final String str) {
        return str.lines()
            .map(this::parseLine)
            .toArray(String[][]::new);
    }
    
    private String[] parseLine(String toParse) {
        String[] line = toParse.split(separator);
        validateLine(line);
        return line;
    }
    
    private void validateLine(String[] line) {
        if (line.length != columnCount) {
            throw new LineParsingException(line, columnCount);
        }
    }
}

Exception example:

private class LineParsingException extends RuntimeException {
    private static final String MESSAGE_TEMPLATE = """
            The actual number of columns in the line
            %s
            doesn't match the expected number of columns %d""";
    
    public LineParsingException(String[] line, int columnsExpected) {
        super(MESSAGE_TEMPLATE.formatted(Arrays.toString(line), columnsExpected));
    }
}
Answer from Alexander Ivanchenko on Stack Exchange
🌐
Baeldung
baeldung.com › home › java › java io › reading a csv file into an array
Reading a CSV File into an Array | Baeldung
May 9, 2025 - Next, let’s use a java.util.Scanner to run through the contents of the file and retrieve lines serially, one by one: List<List<String>> records = new ArrayList<>(); try (Scanner scanner = new Scanner(new File("book.csv"))) { while (scanner.hasNextLine()) { records.add(getRecordFromLine(scanner.nextLine())); } } Next, let’s parse the lines and store them in an array:
🌐
How to do in Java
howtodoinjava.com › home › i/o › parse and read a csv file in java
Parse and Read a CSV File in Java
September 14, 2022 - We can use the delimiter comma to parse the CSV file. The CSV tokens may then be converted into values of different datatypes using the various next() methods. try(Scanner scanner = new Scanner(new File("SampleCSVFile.csv"))){ //Read line while ...
Discussions

parsing - Very simple CSV-parser in Java - Code Review Stack Exchange
Please take a look at my method for parsing a CSV string. I am looking for a simple approach without using an external library. Is throwing a RuntimeException inside the stream appropriate? import ... More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
September 14, 2024
How to parse e.g. a CSV which contains data of different types? (int, double, String...)
CSV's are not standardised. What happens (using split(',') for instance) if any of your values include a ','? For that reason alone use a good CSV library (e.g. Apache Commons). As another comment said you should also consider parsing the row into strings then convert those values into their proper types (int, date, whatever) and finally instantiate instances of an object (or immutable Java record preferably). A list of lists accessed by index doesn't communicate intent, it's error prone and isn't resilient to changing requirements (a new column being inserted for example) Edit: also have you considered your error handling strategy, if a row is missing items, or if an expected int is actually a string? At minimum consider logging the line and line number. More on reddit.com
🌐 r/learnjava
13
4
July 16, 2024
Parsing .csv file using Java 8 Stream - Stack Overflow
I am trying to write a method that takes a string param and this relates to the column title found in the .csv file. Based on this param, I want the method to parse the file using Java 8's Stream functionality and return a list of the data taken from the column title for each row/company. More on stackoverflow.com
🌐 stackoverflow.com
java - Parse from a CSV String instead of a File - Stack Overflow
Communities for your favorite technologies. Explore all Collectives · Ask questions, find answers and collaborate at work with Stack Overflow for Teams More on stackoverflow.com
🌐 stackoverflow.com
🌐
Mkyong
mkyong.com › home › java › how to read and parse csv file in java
How to read and parse CSV file in Java - Mkyong.com
December 26, 2020 - 2.3 The OpenCSV examples to read or parse a CSV file. Read all and returns a List<String[]>.
🌐
Medium
medium.com › @zakariafarih142 › mastering-csv-parsing-in-java-comprehensive-methods-and-best-practices-a3b8d0514edf
Mastering CSV Parsing in Java: Comprehensive Methods and Best Practices | by Zakariafarih | Medium
November 25, 2024 - This article explores various methods to parse CSV files in Java, both with and without external libraries, covering file access techniques and parsing strategies. CSV files are simple text files where each line represents a data record, and each record consists of fields separated by commas.
Top answer
1 of 4
9

Side-effects

Stream.forEach() operation should be utilized with care since it operates via side-effects and should not be used as a substitution of a proper reduction operation.

The way you've written this stream is discouraged by the Stream API documentation because it makes code more cluttered and difficult to follow and more importantly your solution is broken with parallel streams (there should be no assumptions on the nature of the stream in your code).

In this particular case, you should be using Stream.toArray() operation instead.

Multiline lambdas

Try to void them. They bear a lot of cognitive load. If a lambda expression requires several lines or when you have a complex single-line lambda (e.g. with a nested stream in it), consider introducing a method.

Exceptions

In short, the purpose of exceptions is to indicate cases when it's not possible to proceed with the normal execution flow.

If you stumbled on a corrupt piece of data which violates invariant that are important for your business logic, usually you don't want to proceed processing it. That's a valid case to throw. You asked can you "throw from a stream"? Sure, it's just a means iteration.

I've seen some bickering over whether it's appropriate to use exceptions for the purpose of validation. Sure it is, we do employ Exceptions for Validation for decades.

Unless you're using exceptions to avoid conditional logic, or to make weird hacks like throwing in order to break from a recursive method, and you have a genuine invalid piece of data on your hands you can and should throw.

Another, important note: exceptions should be informative. If standard exception types can describe the case at hand, fine, if not introduce your own exception type.

Also, use proper exception messages that will be helpful in investigating the issue.

Static routines

Don't treat everything as util classes, use the Power of object-orientation to make more clean, cohesive and testable.

Refactored version

public class ArrayParser {
    private final String separator;
    private final int columnCount;
    
    public ArrayParser(String separator, int columnCount) {
        this.separator = separator;
        this.columnCount = columnCount;
    }
    
    public String[][] parse(final String str) {
        return str.lines()
            .map(this::parseLine)
            .toArray(String[][]::new);
    }
    
    private String[] parseLine(String toParse) {
        String[] line = toParse.split(separator);
        validateLine(line);
        return line;
    }
    
    private void validateLine(String[] line) {
        if (line.length != columnCount) {
            throw new LineParsingException(line, columnCount);
        }
    }
}

Exception example:

private class LineParsingException extends RuntimeException {
    private static final String MESSAGE_TEMPLATE = """
            The actual number of columns in the line
            %s
            doesn't match the expected number of columns %d""";
    
    public LineParsingException(String[] line, int columnsExpected) {
        super(MESSAGE_TEMPLATE.formatted(Arrays.toString(line), columnsExpected));
    }
}
2 of 4
7

conservative design

Since this is billed as "a CSV parser", a caller may reasonably believe they could send it any *.csv file produced by Excel. Better to advertise it as MyRestrictedCsvParser. The /** javadoc */ comments should explain the restrictions.

  1. Each field may or may not be enclosed in double quotes

This library should probably throw a fatal error upon encountering an ASCII 34 " double quote anywhere in an input line. Then a caller would not accidentally consume a data file in the belief that it had been parsed one way when in fact the library parsed it another way. That is, part of scoping down requirements is reducing the space of inputs you're willing to claim you successfully processed.

informative diagnostic

Throwing an unchecked exception within the JVM is great. It makes your library easier for callers to consume.

                throw new RuntimeException();

This is not a very diagnostic error. It needs two improvements:

  1. Subclass RuntimeException to create a library-specific error, perhaps CsvParseException.
  2. Mention the values of split.length and cols in the message, to save a maintenance engineer a little effort in diagnosing and repairing buggy inputs.

Consider keeping track of which line number we're on, so that can be included in the diagnostic message.

A caller should not be forced to catch a generic RuntimeException to recover from an error it knows how to deal with. We define new app-specific exception types to permit fine-grained catching. Lumping "wrong column count", "found a quote", and "zero lines" together would be acceptable, at least until you see how callers actually behave. If it turns out that callers really do wish to distinguish between those errors, then a v2 library release could always offer finer granularity on the error types.

signature

Clearly the OP code works. It seems slightly less convenient for the caller than it might be. There is redundant information encoded in the str and cols parameters.

Consider setting cols based on number of fields found in the first line of input.

🌐
Attacomsian
attacomsian.com › blog › java-read-parse-csv-file
How to read and parse a CSV file in Java
September 24, 2022 - You can either use the BufferedReader class or the Scanner class to easily read the file in Java. Since CSV is just a plain-text file, the BufferedReader class can be used to read it line by line.
🌐
Reddit
reddit.com › r/learnjava › how to parse e.g. a csv which contains data of different types? (int, double, string...)
r/learnjava on Reddit: How to parse e.g. a CSV which contains data of different types? (int, double, String...)
July 16, 2024 -

My initial thought is to use .split(",") and essentially loop through all elements with calls to Integer.parseInt(), Double.parseDouble()... and store these in their own separate List<String[]>, List<Int[]>, List<Double[]>.

I would want to preserve the row-structure of the original file - i.e., each row might be an individual with columns containing variables like name, age, etc - the i'th row of each List<[]> should therefore refer to the i'th individual. Does this make sense as a solution, and even if it does are there better ways of going about it?

Find elsewhere
🌐
Stack Abuse
stackabuse.com › reading-and-writing-csvs-in-java
Reading and Writing CSVs in Java
February 20, 2019 - Let's consider the steps to open a basic CSV file and parse the data it contains: ... Create a BufferedReader and read the file line by line until an "End of File" (EOF) character is reached · Use the String.split() method to identify the comma delimiter and split the row into fields
🌐
Blogger
javarevisited.blogspot.com › 2015 › 06 › 2-ways-to-parse-csv-files-in-java-example.html
2 Ways to Parse CSV Files in Java - BufferedReader vs Apache Commons CSV Example
August 7, 2021 - You open a CSV file and start reading it line by line, since each line contains a coma separated String, you need to split them using comma (",") and you will get an array of String containing each column.
🌐
How to do in Java
howtodoinjava.com › home › string › split csv string using regex in java
Split CSV String using Regex in Java
February 22, 2023 - We can use a regular expression "\\s*,\\s*" to match commas in CSV string and then use String.split() method to convert string to an array of tokens. String blogName = "how, to, do, in, java"; String[] tokenArray = blogName.split("\\s*,\\s*"); Assertions.assertArrayEquals(new String[]{"how", "to", "do", "in", "java"}, tokenArray);
🌐
Educative
educative.io › answers › how-to-parse-a-csv-file-in-java
How to parse a CSV file in Java
In Java, there are multiple ways of reading and parsing CSV files. The most common ones are: ... In this shot, we will be only looking at the first two methods as they involve built-in libraries. A Scanner in Java can be used to break the input into tokens using delimiters. These tokens are then converted into values of different types using various next-methods. To use this method, we first need to import the Scanner using the statement​ import java.util.Scanner. ... The String.split() function in Java takes tokens from the given string and turns them into tokens that are based on a provided delimiter as a parameter.
Top answer
1 of 4
22

You should not reinvent the wheel and use a common csv parser library. For example you can just use Apache Commons CSV.

It will handle a lot of things for you and is much more readable. There is also OpenCSV, which is even more powerful and comes with annotations based mappings to data classes.

 try (Reader reader = Files.newBufferedReader(Paths.get("file.csv"));
            CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT
                    .withFirstRecordAsHeader()        
        ) {
            for (CSVRecord csvRecord : csvParser) {
                // Access
                String name = csvRecord.get("MyColumn");
                // (..)
          }

Edit: Anyway, if you really want to do it on your own, take a look at this example.

2 of 4
3

I managed to shorten your snippet a bit.

If I get you correctly, you need all values of a particular column. The name of that column is given.

The idea is the same, but I improved reading from the file (it reads once); removed code duplication (like line.split(",")), unnecessary wraps in List (Collectors.toList()).

// read lines once
List<String[]> lines = lines(path).map(l -> l.split(","))
                                  .collect(toList());

// find the title index
int titleIndex = lines.stream()
                      .findFirst()
                      .map(header -> asList(header).indexOf(titleToSearchFor))
                      .orElse(-1);

// collect needed values
return lines.stream()
            .skip(1)
            .map(row -> row[titleIndex])
            .collect(toList());

I've got 2 tips not related to the issue:

1. You have hardcoded a URI, it's better to move the value to a constant or add a method param.
2. You could move the main part out of the if clause if you checked the opposite condition !Files.exists(path) and threw an exception.

🌐
Javatpoint
javatpoint.com › how-to-read-csv-file-in-java
Read CSV File in Java
How to Read CSV File in Java with oops, string, exceptions, multithreading, collections, jdbc, rmi, fundamentals, programs, swing, javafx, io streams, networking, sockets, classes, objects etc,
🌐
Simplesolution
simplesolution.dev › java-read-and-parse-csv-string-using-apache-commons-csv
Read and Parse CSV Content from a String in Java using Apache Commons CSV
args) { String csvContent = "First Name,Last Name,Email,Phone Number\n" + "John,Doe,john@simplesolution.dev,123-456-789\n" + "Emerson,Wilks,emerson@simplesolution.dev,123-456-788\n" + "Wade,Savage,wade@simplesolution.dev,123-456-787\n" + "Star,Lott,star@simplesolution.dev,123-456-786\n" + "Claudia,James,claudia@simplesolution.dev,123-456-785\n"; CSVFormat csvFormat = CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase(); try(CSVParser csvParser = CSVParser.parse(csvContent, csvFormat)) { for(CSVRecord csvRecord : csvParser) { String firstName = csvRecord.get("First Name"); String lastName = csvRecord.get("Last Name"); String email = csvRecord.get("Email"); String phoneNumber = csvRecord.get("Phone Number"); System.out.println(firstName + "," + lastName + "," + email + "," + phoneNumber); } } catch (IOException e) { e.printStackTrace(); } } } The output is:
Top answer
1 of 3
1

You are not reading your file line by line. What you are actually supposed to do is get a line, split it, remove the double quotes and compare to your string. Or you can wrap your input string in a double quote and just compare with the string after splitting. For this try the following code:

Scanner scanner = null;
try {
  scanner = new Scanner(new File(file));

  String s1 = null;
  String id= null;
  String[] tempArr = null;
  String searchStr = "\""+search_field.getText()+"\"";
  System.out.print("searchStr = " + searchStr );

  while(scanner.hasNext()) { // While there are more lines in file 
    s1= scanner.nextLine();
    tempArr = s1.split(","); // use coma_delimiter instead coma_delimiter if coma_delimiter=","
    id = (tempArr != null && tempArr.length > 0? tempArr[0] : null);
    System.out.print("ID = " + id);

    if(id != null && id.equals(searchStr)) {
      System.out.print("OKOK");
      break; // quit the loop searchStr is found
    } else {
    System.out.println("NOK");
    }
  }
} catch (FileNotFoundException fe) {
 fe.printStackTrace();
} finally {
  scanner.close();
}
2 of 3
0

You may want to use Apache Commons CSV instead as this is designed to work with csv file, straight from their page is the below example

Reader in = new FileReader("path/to/file.csv");
Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(in);
for (CSVRecord record : records) {
    String lastName = record.get("Last Name");
    String firstName = record.get("First Name");
}

where "Last Name" and "First Name" are all column names. This way you can clearly check on which column your string is.

Maven dependency below:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.5</version>
</dependency>
🌐
GeeksforGeeks
geeksforgeeks.org › java › reading-csv-file-java-using-opencsv
Reading a CSV file in Java using OpenCSV - GeeksforGeeks
July 11, 2025 - CSVReader csvReader = new CSVReaderBuilder(filereader).withCSVParser(parser).build(); ... // Java code to illustrate // Reading CSV File with different separator public static void readDataFromCustomSeparator(String file) { try { // Create an object of file reader class with CSV file as a parameter.
🌐
Delft Stack
delftstack.com › home › howto › java › parse csv in java
How to Parse CSV in Java | Delft Stack
February 15, 2024 - import java.io.*; import java.util.Scanner; public class Main { public static void main(String[] args) throws FileNotFoundException { String line = ""; final String delimiter = ","; try { String filePath = "/test/example.csv"; FileReader fileReader = new FileReader(filePath); BufferedReader reader = new BufferedReader(fileReader); while ((line = reader.readLine()) != null) // loops through every line until null found { String[] token = line.split(delimiter); // separate every token by comma System.out.println(token[0] + " | " + token[1] + " | " + token[2] + " | " + token[3]); } } catch (IOException e) { e.printStackTrace(); } } } ... Id | UserName | Age | Job 1 | John Doe | 24 | Developer 2 | Alex Johnson | 43 | Project Manager 3 | Mike Stuart | 26 | Designer 4 | Tom Sean | 31 | CEO · Several libraries can help us to parse the CSV in Java.
Top answer
1 of 10
19

There is a serious problem with using

String[] strArr=line.split(",");

in order to parse CSV files, and that is because there can be commas within the data values, and in that case you must quote them, and ignore commas between quotes.

There is a very very simple way to parse this:

/**
* returns a row of values as a list
* returns null if you are past the end of the input stream
*/
public static List<String> parseLine(Reader r) throws Exception {
    int ch = r.read();
    while (ch == '\r') {
        //ignore linefeed chars wherever, particularly just before end of file
        ch = r.read();
    }
    if (ch<0) {
        return null;
    }
    Vector<String> store = new Vector<String>();
    StringBuffer curVal = new StringBuffer();
    boolean inquotes = false;
    boolean started = false;
    while (ch>=0) {
        if (inquotes) {
            started=true;
            if (ch == '\"') {
                inquotes = false;
            }
            else {
                curVal.append((char)ch);
            }
        }
        else {
            if (ch == '\"') {
                inquotes = true;
                if (started) {
                    // if this is the second quote in a value, add a quote
                    // this is for the double quote in the middle of a value
                    curVal.append('\"');
                }
            }
            else if (ch == ',') {
                store.add(curVal.toString());
                curVal = new StringBuffer();
                started = false;
            }
            else if (ch == '\r') {
                //ignore LF characters
            }
            else if (ch == '\n') {
                //end of a line, break out
                break;
            }
            else {
                curVal.append((char)ch);
            }
        }
        ch = r.read();
    }
    store.add(curVal.toString());
    return store;
}

There are many advantages to this approach. Note that each character is touched EXACTLY once. There is no reading ahead, pushing back in the buffer, etc. No searching ahead to the end of the line, and then copying the line before parsing. This parser works purely from the stream, and creates each string value once. It works on header lines, and data lines, you just deal with the returned list appropriate to that. You give it a reader, so the underlying stream has been converted to characters using any encoding you choose. The stream can come from any source: a file, a HTTP post, an HTTP get, and you parse the stream directly. This is a static method, so there is no object to create and configure, and when this returns, there is no memory being held.

You can find a full discussion of this code, and why this approach is preferred in my blog post on the subject: The Only Class You Need for CSV Files.

2 of 10
19

You also have the Apache Commons CSV library, maybe it does what you need. See the guide. Updated to Release 1.1 in 2014-11.

Also, for the foolproof edition, I think you'll need to code it yourself...through SimpleDateFormat you can choose your formats, and specify various types, if the Date isn't like any of your pre-thought types, it isn't a Date.