Java 1-Line Solution via Regex and Stream


  • 54
    L
    public String[] findWords(String[] words) {
        return Stream.of(words).filter(s -> s.toLowerCase().matches("[qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*")).toArray(String[]::new);
    }
    

  • 0
    Q

    Nice one line solution. Thanks for your sharing.
    I feel so amazed that "String[]::new" works, but I never saw this kind of grammar in java, it's more like C++ style, could you pls explain a little bit on that?


  • 3
    L

    String[]::new is a syntax sugar for the lambda expression size -> new String[size].


  • 1
    M

    91 ms.....for 29 test case.


  • 3
    I

    @ming54 Streams were never about performance, they are slower than most other ways of writing the same logic. Their advantage lies in brevity of code.


  • 4
    Y

    @IcyCubic nice solution. but brevity is not advantage for code rather than easy to understand and maintain.


  • 4

    Actually, @lixx2100 's solution is much easier to understand and maintain.
    (Based on my experience in industry.)

    It uses the basic Java 8 stream API and rules out the implementation details like if or for loops, which are usually error probing. The logic is very clear for those familiar with Java 8. (We should when we at work.)

    I would suggest breaking the code into multiple lines which make the logic look clearer. (As we do when writing JS Promise.)

    public class Solution {
        public String[] findWords(String[] words) {
            String keyboardRegex = "[qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*";
            return Stream.of(words)
                .filter(word -> word.toLowerCase().matches(keyboardRegex))
                .toArray(String[]::new);
        }
    }
    

  • 2

    @qlan2 said in Java 1-Line Solution via Regex and Stream:

    String[]::new

    Without String[]::new, toArray() returns an Object array. Therefore, we need to use

    xxxxxx.toArray(String[]::new)
    

  • 0
    E

    JS version

    const findWords = (words) => {
        return words.filter((word) => /^[qwertyuiop]*$|^[asdfghjkl]*$|^[zxcvbnm]*$/g.test(word.toLowerCase()))
    }
    

  • 0
    K

    @lixx2100 What is the complexity of this solution?


  • 1
    X

    @lixx2100 The regex " [qwertyuiop]+|[asdfghjkl]+|[zxcvbnm]+" may be better because if the input is ["","Dad"], ["Dad"] should be output rather than ["","Dad"].


  • 0
    S

    One part I don't understand is that if you have a string "asdft", it would match the first regular expression, as it still contains 0* characters from second line of the keyboard; and will be included in the answer. But it really should not due to the presence of "t".


  • 0
    A

    I use scala
    object Solution {
    def findWords(words: Array[String]): Array[String] = words.filter(_.toLowerCase.matches("[qwertyuiop]|[asdfghjkl]|[zxcvbnm]*"))
    }


  • 0

    With Java 8 streams, 1-liner does not only belong to Python and Ruby anymore :-)


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.