-1

I want to write code in Java 8 for saving data from text file in List. I have to use streams. Data must be saved in List from concrete line. For example:

My text file:

House
Tree
Pillow
Sky

I want to save data in List from line with "Pillow" (regular expression). Expected result (in my List):

Pillow
Sky

Question: How to start save data from file into list from line when filter() is matching?

John Doe
  • 319
  • 2
  • 5
  • 24

6 Answers6

0

if you want to skip the first two items on a file, you can do this:

public static void main(String[] args) {
        String fileName = "/home/daniel/doc"; //text file location
        int n = 2; //you can set the amount of items you want to skip
        try (Stream<String> stream = Files.lines(Paths.get(fileName))) {

            stream
            .skip(n) //skip the first n numbers
            .forEach(System.out::println);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
dsncode
  • 2,407
  • 2
  • 22
  • 36
0

Streams are not required here. If the language has support for some features it doesn't matter that you should do anything using streams/lambdas. In Java 8 you already has beautiful Files class for such actions.

public static List<String> getLines(String filePath) throws IOException {
    Path file = Paths.get(filePath);
    List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
    return new ArrayList<>(lines.subList(2, lines.size() - 1));
}

You can replace hardcoded index with more complicated logic to determine it.

Hope it helps!

Sergey Prokofiev
  • 1,815
  • 1
  • 12
  • 21
0

You can try this snippet:

static boolean isPresent = false;
    public static void main(String[] args) {
        List<String> list =Stream.of("House","Tree","Pillow","Sky")
                .filter((s)-> {
                    if(!isPresent){
                    isPresent=s.equals("Pillow");
                    }
                    return isPresent;
                })
                .collect(Collectors.toList());
        System.out.println(list);
    }
xyz
  • 812
  • 9
  • 18
  • I didn't see your answer when I posted mine ;) Your filter condition is better but I think using a wrapper class is better than using static variable. If you have two threads that static variable can cause a problem – Veselin Davidov Apr 18 '18 at 06:41
0

now, if you want to use regular expression, you could do as follows

public static void main(String[] args) {
        String fileName = "/home/daniel/Desktop/doc"; //text file location
        String regex = "Pillow|Sky"; // add your regular expression here 
        Pattern p = Pattern.compile(regex);
        try (Stream<String> stream = Files.lines(Paths.get(fileName))) {

            List<String> filteredList = stream
            .filter(str->p.matcher(str).matches())
            .collect(Collectors.toList()); //collect items into a list

            filteredList.stream().forEach(System.out::println);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
dsncode
  • 2,407
  • 2
  • 22
  • 36
0

If you want to filter the stream by to print lines after matching specific value maybe stream is not the best way to do it. It is not intended to keep state and you need to keep a state here (have you already reached the value).

You can do it with streams and filters like that:

public class MainClass {
    public static void main(String[] args) {
                System.out.println(new Date()+": Let's start our StackOverflow helper project!");

                List<String>  res= Arrays.asList("house","Tree","Pillow","Sky");
                BooleanWrapper valueFound = new BooleanWrapper();
                        List<String> result = res.stream()                
                                .filter(string -> valueFound.value || "Pillow".equals(string)  && (valueFound.value = true))   
                                .collect(Collectors.toList());             
                result.forEach(System.out::println);             

    }


}
class BooleanWrapper {
    boolean value=false; 
}

Notice how we need to wrap our boolean value into a class. If we just use primitive we need to define it as final in order to access it in the stream and that means we cannot change it to true when we find it.

Also this is kind of a hack. It works because we do the assignment valueFound.value = true last in the filter and it happens ONLY if the other conditions are met. If we change the order of the boolean tests there it will not work.

Veselin Davidov
  • 7,031
  • 1
  • 15
  • 23
0

You can get the result set by the following method:

public Set<String> getNames() throws IOException {
    BufferedReader br;
    FileInputStream inputStream = new FileInputStream("src/test/java/com/job/test.txt");
    br = new BufferedReader(new InputStreamReader(inputStream));
    String line;
    List<String> fileStrings = new ArrayList<>();
    while ((line = br.readLine()) != null){
        fileStrings.add(line);
    }
    List<String> names = Arrays.asList("Pillow", "Sky");

    return fileStrings.stream().filter(names::contains).collect(Collectors.toSet());
}
buddha
  • 795
  • 5
  • 11