I'm facing an odd issue
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Created by mklueh on 13/09/2022
*/
public class Reproducer {
private static final String COMMA_SEPARATED_STRING = "2020-05-09,hello ,10 ,11.345 ,true ,1000000000000";
/**
* Not working
*/
@Nested
public class WithReturn {
public String withReturn(Stream<String> stream, String delimiter, Function<? super String, String[]> tokenizer) {
return stream.map(s -> {
return Arrays.stream(tokenizer != null ? tokenizer.apply(s) : s.split(delimiter))
.map(String::strip) //Comment out to make it compile
.collect(Collectors.toList());
})
.flatMap(Collection::stream)
.collect(Collectors.joining(","));
}
@Test
void usingDelimiter() {
assertEquals(COMMA_SEPARATED_STRING.replaceAll(" ", ""),
withReturn(Stream.of(COMMA_SEPARATED_STRING), ",", null));
}
@Test
void usingTokenizer() {
assertEquals(COMMA_SEPARATED_STRING.replaceAll(" ", ""),
withReturn(Stream.of(COMMA_SEPARATED_STRING), null, s -> s.split(",")));
}
}
/**
* Working
*/
@Nested
public class WithReturnAndStripLambda {
public String withReturnAndStripLambda(Stream<String> stream, String delimiter, Function<? super String, String[]> tokenizer) {
return stream.map(s -> {
return Arrays.stream(tokenizer != null ? tokenizer.apply(s) : s.split(delimiter))
.map(s1 -> s1.strip())
.collect(Collectors.toList());
})
.flatMap(Collection::stream)
.collect(Collectors.joining(","));
}
@Test
void usingDelimiter() {
assertEquals(COMMA_SEPARATED_STRING.replaceAll(" ", ""),
withReturnAndStripLambda(Stream.of(COMMA_SEPARATED_STRING), ",", null));
}
@Test
void usingTokenizer() {
assertEquals(COMMA_SEPARATED_STRING.replaceAll(" ", ""),
withReturnAndStripLambda(Stream.of(COMMA_SEPARATED_STRING), null, s -> s.split(",")));
}
}
/**
* Working
*/
@Nested
public class WithMethodExpression {
public String withMethodExpression(Stream<String> stream, String delimiter, Function<? super String, String[]> tokenizer) {
return stream.map(s -> Arrays.stream(tokenizer != null ? tokenizer.apply(s) : s.split(delimiter))
.map(String::strip)
.collect(Collectors.toList())
)
.flatMap(Collection::stream)
.collect(Collectors.joining(","));
}
@Test
void usingDelimiter() {
assertEquals(COMMA_SEPARATED_STRING.replaceAll(" ", ""),
withMethodExpression(Stream.of(COMMA_SEPARATED_STRING), ",", null));
}
@Test
void usingTokenizer() {
assertEquals(COMMA_SEPARATED_STRING.replaceAll(" ", ""),
withMethodExpression(Stream.of(COMMA_SEPARATED_STRING), null, s -> s.split(",")));
}
}
}
invalid method reference
error: incompatible types: invalid method reference
.map(String::strip)
^
method strip in class String cannot be applied to given types
required: no arguments
found: long
reason: actual and formal argument lists differ in length
And the IntelliJ IDEA even recommends to perform the auto-refactoring to get rid of the lambda function in favor of the method reference
as well as replacing the return with expression lambda
What is wrong here and why does IntelliJ recommend to break code / not recognize that the recommendation is causing compiler errors?


.stream(tokenizer != null ? tokenizer.apply(s) : s.split(delimiter))is entirely unrelated to the subsequentmapcall. As already said, you should post a minimal reproducible example.tokenizer.apply(s)returning a different type could not explain an error message about alongargument found when using this method reference. Having a workaround is not the same as solving (and hence understanding) the problem. Otherwise, you could have stayed with the lambda expression.String[]. If you are able to reproduce the problem, it shouldn’t be so hard to provide a minimal reproducible example. I don’t understand why you don’t do this.List(with.collect(Collectors.toList())) and then again streaming over it (using.flatMap(Collection::stream)). Remove thetoList()part and then useflatMap(Function.identity()), as you are already returning aStreaminside the previous step.