4

Java 8.

Converting a forEach loop into a lambda expression is understood, at least for me. Converting a for loop based with a condition, in the other hand, isn't.

If it's possible ,my question would be: how can you convert the following for loop into a lambda expression

List<Field> fields = new LinkedList<>();
        for (Class<?> c = this.getClass(); c != null; c = c.getSuperclass())
            Collections.addAll(fields, c.getDeclaredFields());

Many thanks in advance,

~Ben.

7
  • Lambda isn't going to help you here. If you want to get all fields of class including inherited, try this solution: stackoverflow.com/questions/1042798/… Commented Mar 1, 2017 at 9:46
  • I disagree with the accepted answer that recursion is the better approach, second my inductive code works better. Commented Mar 1, 2017 at 9:50
  • Stream s direct replacement for for-each style. But here, you can't either flatten the stream, what you need is iterate over the stream by yourself. Which means, internal iteration will not help you. Commented Mar 1, 2017 at 9:51
  • I would love to know if my question is even possible Commented Mar 1, 2017 at 9:52
  • 2
    Related: Streaming a class hierarchy Commented Mar 1, 2017 at 12:51

2 Answers 2

5

Well, there is a way, but it needs takeWhile that it is in jdk-9.

I'm doing a mapping here to get the names of the fields. You would have to add a @SuppressWarnings("null") to the method.

System.out.println(Stream.iterate(this.getClass(), (Class<?> x) -> x.getSuperclass())
            .takeWhile(x -> x != null)
            .flatMap(c -> Arrays.stream(c.getDeclaredFields()))
            .map(c -> c.getName())
            .collect(Collectors.toList()));

jdk-9 also introduces a Stream.iterate that acts like an Iterator with seed, hasNext, next that is far more suited for your case.

You could use StreamEx library for this btw:

 StreamEx.of(Stream.iterate(this.getClass(), (Class<?> x) -> x.getSuperclass()))
            .takeWhile(x -> x != null)
            .flatMap(c -> Arrays.stream(c.getDeclaredFields()))
            .map(c -> c.getName())
            .collect(Collectors.toList());

And with new iterate method:

 Stream.iterate(this.getClass(), c -> c != null, (Class<?> c) -> c.getSuperclass())
            .flatMap(c -> Arrays.stream(c.getDeclaredFields()))
            .map(c -> c.getName())
            .collect(Collectors.toList())
Sign up to request clarification or add additional context in comments.

4 Comments

Stream.iterate(this.getClass(), c -> c != null, (Class<?> c) -> c.getSuperclass()) .flatMap(c -> Arrays.stream(c.getDeclaredFields())) .map(c -> c.getName()) .collect(Collectors.toList())
is it only possible with java9 ?
@Benma you need takeWhile for it to work in jdk-8. This is either in StreamEx library or you can add it yourself until available from here: stackoverflow.com/questions/20746429/…
@Roland indeed, a Stream out of the Iterator.
0

You maybe want to work with streams. Open a stream on your list and simply use filter. Filter takes a FunctionalInterface/Lambda-expression.

1 Comment

I'm well familiar with streams and filters, but to implement the following loop condition with these methods isn't straightforward to me for some reason, is there any chance for a code snippet?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.