2

So I have this POJO class:

public class Player {

 @CsvBindByName
 private String simTime;

 @CsvBindByName
 private String playerId;

 @CsvBindByName
 private String dimX;

 @CsvBindByName
 private String offX;

 @CsvBindByName
 private String dimY;

 @CsvBindByName
 private String roadS;

 @CsvBindByName
 private String roadT;

 public String getSimTime() {     
    return simTime;
 }

 public void setSimTime(String simTime) {
    this.simTime = simTime;
 }

 public String getPlayerId() {
    return playerId;
 }

 public void setPlayerId(String playerId) {
    this.playerId = playerId;
 }

 public String getDimX() {
    return dimX;
 }

 public void setDimX(String dimX) {
    this.dimX = dimX;
 }

 public String getOffX() {
    return offX;
 }

 public void setOffX(String offX) {
    this.offX = offX;
 }

 public String getDimY() {
    return dimY;
 }

 public void setDimY(String dimY) {
    this.dimY = dimY;
 }

 public String getRoadS() {
    return roadS;
 }

 public void setRoadS(String roadS) {
    this.roadS = roadS;
 }

 public String getRoadT() {
    return roadT;
 }

 public void setRoadT(String roadT) {
    this.roadT = roadT;
 }

 @Override
 public String toString() {
    return "Player{" + "simTime=" + simTime + ", playerId=" + playerId + ", dimX=" + dimX + ", offX=" + offX + ", dimY=" + dimY + ", roadS=" + roadS + ", roadT=" + roadT + '}';
 }

}

And I have a large excel file with a LOT MORE columns. One of the columns in my excel file is called objectId.

Using this code:

private void loadCSVFiles() throws Exception {
    List<Player> beans = new CsvToBeanBuilder(new FileReader("C:\\Users\\noname\\Desktop\\ABP_S31\\ABP20180809_S31_FG_Notbremsung_100.csv"))
            .withType(Player.class)
            .withIgnoreLeadingWhiteSpace(true)
            .build()
            .parse();
    beans.forEach(System.out::println);

}

I managed to get specific columns which I need. The problem I am having is that right now I only need rows where the playerId equals objectId. Obviously I could add objectId as a class property and after I load the file I could go through the entire list and filter the rows AGAIN. But I don't want to this as

  1. performance issues
  2. objectId has actually nothing to do with my Player class

Also I could load the entire excel file and filter the columns, but I also don't want this because for me personally it is more readable if I do this the current way. Is there a way to solve this problem or do I have to use the options above?

I tried using csvToBeanFilter but the getColumnIndex method is deprecated: docu

kokos123
  • 305
  • 3
  • 11

1 Answers1

0

So if you know the column headers, and you're sure they won't change in the future, you could implement a CsvToBeanFilter using a custom HeaderColumnNameMappingStrategy. This way you can avoid the deprecated getColumnIndex() method.

private class MyStrategy<T> implements HeaderColumnNameMappingStrategy<T> {

  private int playerIndex;
  private int objectIndex;

  @Override
  public void captureHeader(CSVReader reader) throws IOException {

    // make sure to call super() first because it will retrieve the header variable
    super();

    // inspect the header and store the relevant indices for later use
    for(int i = 0; i < header.length; i++)
    {
      if("objectId".equals(header[i])
        objectIndex = i;
      else if("playerId".equals(header[i])
        playerIndex = i;
    }
  }

  public int getPlayerIndex(){ return playerIndex; }
  public int getObjectIndex(){ return objectIndex; }
}

Use it in the Filter

private class MyFilter implements CsvToBeanFilter {

  private final MappingStrategy strategy;

  public MyFilter(MappingStrategy strategy) {
    this.strategy = strategy;
  }

  public boolean allowLine(String[] line) {
    // restore the relevant indices from the strategy
    int playerIndex = strategy.getPlayerIndex();
    int objectIndex = strategy.getObjectIndex();
    String playerId = line[playerIndex];
    String objectId = line[objectIndex];

    return playerId.equals(objectId);
  }
}

And now you can add the Filter to the CsvToBeanBuilder.

private void loadCSVFiles() throws Exception {
  MappingStrategy strategy = new MyStrategy();
  List<Player> beans = new CsvToBeanBuilder(new FileReader("C:\\Users\\noname\\Desktop\\ABP_S31\\ABP20180809_S31_FG_Notbremsung_100.csv"))
          .withType(Player.class)
          .withIgnoreLeadingWhiteSpace(true)
          .withMapper(strategy)
          .withFilter(new MyFilter())
          .build()
          .parse();
  beans.forEach(System.out::println);

}
Sparkofska
  • 1,280
  • 2
  • 11
  • 34
  • is a deprecated method. Because when I implement the code the method is strikethroughed.. Here it says it is deprecated: http://opencsv.sourceforge.net/apidocs/com/opencsv/bean/MappingStrategy.html – kokos123 Aug 20 '18 at 14:19
  • edited: implement custom MappingStrategy in order to bypass deprecated method – Sparkofska Aug 20 '18 at 15:54