Search code examples
javafilterjava-stream

Filtering the value using java 8 map


I am working of CSV file reader . Need to replace first and last word of 12345,sdc,CAP,12345:sdc-posistion-svc:SnakeYAML:2.1:3 (12345 and 3) from above lines an replace ": with ","

Sample CSV file

col1,col2,col3,col4,col5,col6,col7,col8
CVM Finding,12345,sdc,CAP,12345:sdc-posistion-svc:SnakeYAML:2.1:3,TRUE,FALSE,OverDue
CVM Finding,12345,sdc,CAP,12345:sdc-event-generation-svc:SpringBoot:2.1.2.Release:1,TRUE,FALSE,Overdue
CVM Finding,12345,sdc,CAP,12345:sdc-event-subscription-svc:Apache Tomcat:9.0.70:1,TRUE,FALSE,Due in <= 90
CVM Finding,12345,sdc,CAP,12345:sdc-bh-registry-svc:Jettison - Json Stax implementation:1.5.3:1,TRUE,FALSE,Due in <=90
CVM Finding,12345,sdc,CAP,12345:sdc-event-generation-svc:Apache Tomcat:9.0.70:2,TRUE,FALSE,Due in >90
CVM Finding,12345,sdc,CAP,12345:sdc-posistion-svc:jackson-databind:2.14:1,TRUE,FALSE,OverDue
CVM Finding,12345,sdc,CAP,12345:sdc-event-subscription-svc:jackson-databind:2.14:1,TRUE,FALSE,Due in <= 90
CVM Finding,12345,sdc,CAP,12345:sdc-event-subscription-svc:SpringBoot:2.1.2.Release:1,TRUE,FALSE,Overdue
CVM Finding,12345,sdc,CAP,12345:sdc-posistion-svc:SpringBoot:2.1.2.Release:1,TRUE,FALSE,OverDue

With below code

public static void getData3() throws IOException 
    {
        MyClass myClass = new MyClass(5, 7);
        String titleForCol5 = "col5";
        String titleForCol8 = "col8";
        
        Path path = Paths.get("D:/blackduck_sample.txt");

        if (Files.exists(path)) {
            List<String> lines = Files.readAllLines(path);

            List<String> columns = Arrays.asList(lines.get(0).split(","));

            int col5Idex = columns.indexOf(titleForCol5);
            int col8Idex = columns.indexOf(titleForCol8);

            List<String> values2 = lines.stream().skip(1).map(line -> Arrays.asList(line.split(",")))
                    .map(list -> list.get(col5Idex).concat(",").concat(list.get(col8Idex))).filter(Objects::nonNull).filter(s -> s.trim().length() > 0)
                    .collect(Collectors.toList());
            
            values2.forEach(System.out::println);
        }
        
    }

I am getting

12345:sdc-posistion-svc:SnakeYAML:2.1:3,OverDue
12345:sdc-event-generation-svc:SpringBoot:2.1.2.Release:1,Overdue
12345:sdc-event-subscription-svc:Apache Tomcat:9.0.70:1,Due in <= 90

I want to change each line from the above output like the one below.

remove the first and last word of the first field and replace ":" with ",".

sdc-posistion-svc,SnakeYAML,2.1,OverDue
sdc-event-generation-svc,SpringBoot,2.1.2.Release,Overdue
sdc-event-subscription-svc,Apache Tomcat,9.0.70,Due in <= 90

Is it possible to do this on the same map?

I tried without java 6 map as below

List<String> lines =  Files.readAllLines(file.toPath(),StandardCharsets.UTF_8); 
              for (String line : lines) {
              String[] array = line.split(",");
              String tempStr =  array[4].replaceAll(":", ",") ;
              System.out.println(tempStr); 
              String shortened = tempStr.substring(0, tempStr.lastIndexOf(',', tempStr.length() - 2));            
              String shortened1 = shortened.replaceFirst("\\b\\w+\\b","").substring(1)+","+array[7];
              
              System.out.println(shortened1); //
              System.out.println(lst.add(array[4].replaceAll(":", ","))); }

I want to do it better way using map


Solution

  • You should add a method and and then use it in map, that way you can add more features in future + your stream does not look too complicated:

    private static String postProcess(String line) {
            String[] array = line.split(",");
            String tempStr =  array[0].replaceAll(":", ",") ;
            return tempStr.substring(0,
                    tempStr.lastIndexOf(',', tempStr.length() - 2))
                    .replaceFirst("\\b\\w+\\b","")
                    .substring(1) + "," + array[1];
        }
    

    Then use it like:

    List<String> values2 = lines.stream().skip(1).map(line -> Arrays.asList(line.split(",")))
                        .map(list -> list.get(col5Idex).concat(",").concat(list.get(col8Idex)))
                        .filter(s -> s.trim().length() > 0)
                        .map(ClassName::postProcess)
                        .toList();