CSVを読み込んで処理する csv4j の利用をラムダ式で書きたくなってきた。
ラムダ式の対象にしたいのは、CSVLineProcessor を使う CSVStreamProcessor である。
ラムダ式にしないこれまでの使用サンプル
try{
CSVStreamProcessor csvStreamProcessor = new CSVStreamProcessor();
csvStreamProcessor.processStream(new InputStreamReader(new FileInputStream("item.csv"), "UTF-8")
, new CSVLineProcessor(){
@Override
public void processHeaderLine(int linenumer, List fields){
// header Line
}
@Override
public void processDataLine(int linenumber, List fields) {
System.out.println("line " + linenumber + " : " + fields.get(3));
}
@Override
public boolean continueProcessing() {
return true;
}
});
}catch(Exception e){
e.printStackTrace();
}
いろんな処理を埋め込めるので良いのだけど、いつもこんなに長く書くのがめんどうに感じてきた。
CSVLineProcessor を継承したCSVデータ行以外の処理を default にする。
CSVStreamProcessor を継承して、新しいprocessStream メソッドを用意する。
あまり良い名称が思いつかないので、"CSV" → "Csv" が付く名称にする。
import java.util.List;
import net.sf.csv4j.CSVLineProcessor;
/**
* CsvLineProcessor
*/
@FunctionalInterface
public interface CsvLineProcessor extends CSVLineProcessor{
@Override
default public boolean continueProcessing(){
return true;
}
@Override
default public void processHeaderLine(int linenumber, List<String> fieldNames){
processDataLine(linenumber, fieldNames);
}
}
新しい、CsvStreamProcessor で、この CsvLineProcessor
を呼ぶ。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import net.sf.csv4j.CSVReader;
import net.sf.csv4j.CSVStreamProcessor;
import net.sf.csv4j.ParseException;
import net.sf.csv4j.ProcessingException;
/**
* CsvStreamProcessor
*/
public class CsvStreamProcessor extends CSVStreamProcessor{
public void processStream(InputStreamReader inReader, CsvLineProcessor processor) throws IOException, ProcessingException, ParseException{
CSVReader reader = new CSVReader(new BufferedReader(inReader), getComment());
try{
int lineCount = 0;
while(processor.continueProcessing()){
List<String> fields = reader.readLine();
if (fields.size()==0) break;
try{
if (isHasHeader() && lineCount==0){
processor.processHeaderLine(reader.getLineNumber(), fields);
}else{
processor.processDataLine(reader.getLineNumber(), fields);
}
}catch(Exception e){
throw new ProcessingException(e, reader.getLineNumber());
}
lineCount++;
}
}finally{
reader.close();
}
}
}
ラムダ式で、以下のように書ける。。。
try{
CsvStreamProcessor csvStreamProcessor = new CsvStreamProcessor();
csvStreamProcessor.processStream(new InputStreamReader(new FileInputStream("item.csv"), "UTF-8")
, (n, l)->{
if (n==1){
// header Line
}else{
System.out.println("line " + n + " : " + l.get(3));
}
});
}catch(Exception e){
e.printStackTrace();
}