将String拆分为Stream 的最佳方法是什么?
我看到了这些变化:
Arrays.stream("b,l,a".split(","))Stream.of("b,l,a".split(","))Pattern.compile(",").splitAsStream("b,l,a")我的优先事项是:
一个完整的,可编译的例子:
import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class HelloWorld {
public static void main(String[] args) {
stream1().forEach(System.out::println);
stream2().forEach(System.out::println);
stream3().forEach(System.out::println);
}
private static Stream<String> stream1() {
return Arrays.stream("b,l,a".split(","));
}
private static Stream<String> stream2() {
return Stream.of("b,l,a".split(","));
}
private static Stream<String> stream3() {
return Pattern.compile(",").splitAsStream("b,l,a");
}
}
Run Code Online (Sandbox Code Playgroud) 我偶然发现了以下使用方法参考的Java代码 System.out.println
class SomeClass{
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9);
numbers.forEach(System.out::println);
}
}
}
Run Code Online (Sandbox Code Playgroud)
什么是等效的lambda表达式System.out::println?
是否有可能null在Java中的引用上创建方法引用
?这样做可能永远不会正确,但可能导致以后很难找到的错误:
public class Test {
void m() {
}
public static void main(String[] args) {
Test test = null;
Runnable fn = test::m; // no exception
System.out.println(fn); // prints Test$$Lambda$1/791452441@1c20c684
fn.run(); // throws a null pointer exception
}
}
Run Code Online (Sandbox Code Playgroud) 据我所知,lambda表达式可以被方法引用替换而没有任何问题.我的IDE说的相同,但下面的例子显示了相反的情况.方法引用清楚地返回相同的对象,其中lambda表达式每次都返回新对象.
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Instance {
int member;
Instance set(int value){
this.member = value;
return this;
}
@Override
public String toString() {
return member + "";
}
public static void main(String[] args) {
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4);
Stream<Integer> stream2 = Stream.of(1, 2, 3, 4);
List<Instance> collect1 = stream1.map(i -> new Instance().set(i)).collect(Collectors.toList());
List<Instance> collect2 = stream2.map(new Instance()::set).collect(Collectors.toList());
System.out.println(collect1);
System.out.println(collect2);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的输出:
[1, 2, 3, 4]
[4, 4, 4, 4]
Run Code Online (Sandbox Code Playgroud) 我想知道我List<T>是否有重复的元素。
我看过下面的方法:
public static <T> boolean areAllUnique(List<T> list){
return list.stream().allMatch(new HashSet<>()::add);
}
Run Code Online (Sandbox Code Playgroud)
它有效,我很惊讶为什么?因为似乎每次都会创建一个新的 HashSet<> (所以基本上该方法应该总是返回 true 即使重复)
如果我以不同的方式编写上述方法,它将不再有效:
public static <T> boolean areAllUnique(List<T> list){
return list.stream().allMatch(t -> {
return new HashSet<>().add(t);
});
}
Run Code Online (Sandbox Code Playgroud)
我很惊讶第一种方法有效而另一种方法无效。因为对我来说它们看起来一样
我希望两个put操作在下面的代码中抛出一个NullPointerException,但实际上lambda表达式工作正常,而方法引用只抛出一个NPE.
public static void main(String... args) {
Object object = null;
Map<String, FuncInterface> map = new HashMap<>();
map.put("key1", () -> object.notify()); // works
map.put("key2", object::notify); // throws NPE
}
@FunctionalInterface
private interface FuncInterface {
public void someAction();
}
Run Code Online (Sandbox Code Playgroud)
有什么不同?
代码:
@FunctionalInterface
interface VoidSupplier {
void apply() throws Exception;
}
void execute(VoidSupplier voidSupplier) {
if (voidSupplier != null) {
try {
voidSupplier.apply();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
调用execute使用lambda:
@Test
public void testLambda() {
InputStream i = null;
execute(() -> i.close()); // use lambda
System.out.println("output some message"); // will be executed
}
Run Code Online (Sandbox Code Playgroud)
调用execute使用方法参考:
@Test
void testMethodReference() {
InputStream i = null;
execute(i::close); // use method reference
System.out.println("output some message"); …Run Code Online (Sandbox Code Playgroud)