javaeclipse

Java 24 Preview Features Not able to access


I am trying to access to Java 24 features. But not able to access. I am using below program

public static void main(String[] args) {
        Stream.of("apple", "banana", "kiwi")
              .gather((word, out) -> {
                  for (char ch : word.toCharArray()) {
                      if (Character.isLowerCase(ch)) {
                          out.accept(ch); // emit each lowercase letter
                      }
                  }
              })
              .forEach(System.out::println);
    }

But its giving me below compile time exception

The method gather(Gatherer<? super String,?,R>) in the type Stream<String> is not applicable for the arguments ((<no type> word, <no type> out) -> {})

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
    The method gather(Gatherer<? super String,?,R>) in the type Stream<String> is not applicable for the arguments ((<no type> word, <no type> out) -> {})
    Lambda expression's signature does not match the signature of the functional interface method integrator()

I have enable preview features from properties

enter image description here

But still not able to run preview features. Am I missing anything here?

I ma using eclipse latest version 2025-03, 4.35


Solution

  • Gatherers are not a preview feature anymore in Java 24. The issue is that you're using a non-compatible lambda.

    Gatherer is a functional interface, but the single method you must implement is integrator(). That requires no arguments. The integrator itself can also be defined as a lambda and takes not 2 but 3 arguments: the intermediate state, the element, and the downstream. In other words (and since the intermediate state is not used, let's make that clear using _):

    Stream.of("apple", "banana", "kiwi").gather(() -> (_, word, downstream) -> {
        for (char ch : word.toCharArray()) {
            if (Character.isLowerCase(ch)) {
                downstream.push(ch);
            }
        }
        return true;
    }).forEach(System.out::println);
    

    Slightly improved to make more use of a possible false return of downstream.push (no need to push if the downstream doesn't want more data):

    Stream.of("apple", "banana", "kiwi").gather(() -> (_, word, downstream) -> word.chars()
            .filter(Character::isLowerCase)
            .allMatch(ch -> downstream.push((char) ch))
    ).forEach(System.out::println);
    

    Now, that doesn't look pretty with the nested lambda, so I'd use the static factory method:

    Stream.of("apple", "banana", "kiwi").gather(Gatherer.of((_, word, downstream) -> word.chars()
            .filter(Character::isLowerCase)
            .allMatch(ch -> downstream.push((char) ch))
    )).forEach(System.out::println);
    

    (Note that I'm not using Integrator.of because I don't see much use in it here. I'm also not making the integrator greedy because it simply doesn't need to be.)