Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8200425

String::lines

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 11
    • core-libs
    • None
    • minimal
    • Java API
    • SE

      Summary

      Add an instance method to java.lang.String that returns a stream of the lines of the contents of a multi-line string.

      Problem

      With the introduction of JEP 326 Raw String Literals, it is expected that developers will make routine use of multi-line strings in their applications. To facilitate processing of multi-line strings it will be common for developers to break those strings down into collections of lines.

      The existing techniques for production of collections of lines vary depending on the application goals. If the developer wants to use streams and functional coding style, then the techniques available can be cumbersome.

      Ex 1.
          Stream<String> lines = List.of(string.split(`\n|\r\n|\r`)).stream();
      
      Ex 2. (more recently)
          Stream<String> lines = List.of(string.split(`\R`)).stream();
      
      Ex 3.
          Stream<String> lines = Pattern.compile(`\R`).splitAsStream​(string);
      
      Ex 4.
          Stream<String> lines = new BufferedReader​(new StringReader​(string)).lines();

      Beside being cumbersome, examples 1 & 2 require additional memory for an intermediate array and all line substrings up front.

      Solution

      Introduce a String instance method that uses a specialized Spliterator to lazily provide lines from the source string.

          Stream<String> lines = string.lines();

      This method simplifies the developer code, significantly reduces memory requirements and is an order of magnitude faster that any previously subscribed code pattern.

      Ex.
          String trimmedLines = string.lines()
                                      .map(String::trim)
                                      .collect(joining("\n"));

      Specification

          /**
           * Returns a stream of substrings extracted from this string
           * partitioned by line terminators.
           * <p>
           * Line terminators recognized are line feed
           * {@code "\n"} ({@code U+000A}),
           * carriage return
           * {@code "\r"} ({@code U+000D})
           * and a carriage return followed immediately by a line feed
           * {@code "\r\n"} ({@code U+000D U+000A}).
           * <p>
           * The stream returned by this method contains each line of
           * this string that is terminated by a line terminator except that
           * the last line can either be terminated by a line terminator or the 
           * end of the string.
           * The lines in the stream are in the order in which
           * they occur in this string and do not include the line terminators
           * partitioning the lines.
           *
           * @implNote This method provides better performance than
           *           split("\R") by supplying elements lazily and
           *           by faster search of new line terminators.
           *
           * @return  the stream of strings extracted from this string
           *          partitioned by line terminators
           *
           * @since 11
           */
          public Stream<String> lines() {

            jlaskey Jim Laskey
            jlaskey Jim Laskey
            Sundararajan Athijegannathan, Xueming Shen
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: