Java8Lambdas和Streams。。。不是",;“如何”,但是一个",;为什么;?

Java8Lambdas和Streams。。。不是",;“如何”,但是一个",;为什么;?,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我的问题涉及Lambdas和Streams。有几件事我无法解决。从lambdas开始,以谓词为例 请注意,在下面的代码中,我既没有导入“java.util.function.Predicate”,也没有在类声明中实现谓词接口。然而,Lambda工作得很好。为什么呢 public class Using_Predicate { public static List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8,

我的问题涉及Lambdas和Streams。有几件事我无法解决。从lambdas开始,以谓词为例

请注意,在下面的代码中,我既没有导入“
java.util.function.Predicate
”,也没有在类声明中实现谓词接口。然而,Lambda工作得很好。为什么呢

public class Using_Predicate {
    public static List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

    public static void main(String[] args) {
        // passing the numbers List and different Lambdas to the intermediate
        // function.
        System.out.println();
        printVals(numbers, x -> x > 6); // all values greater than 6
        System.out.println();
        printVals(numbers, x -> x % 2 == 0); // all even values
        System.out.println();
        printVals(numbers, x -> x < 8); // ll values less than 8
        System.out.println();
        printVals(numbers, x -> x % 2 == 1); // all odd values
    }

    //intermediate Predicate function
    public static void printVals(List<Integer> val, Predicate<Integer>
            condition) {
        for (Integer v : val) {
            if (condition.test(v)) // if true, print v
                System.out.print(v + " ");
        }
    }
}
使用\u谓词的公共类{
公共静态列表编号=数组.asList(1,2,3,4,5,6,7,8,9,10);
公共静态void main(字符串[]args){
//将数字列表和不同的lambda传递给中间层
//功能。
System.out.println();
printVals(数字,x->x>6);//所有大于6的值
System.out.println();
printVals(数字,x->x%2==0);//所有偶数值
System.out.println();
printVals(数字,x->x<8);//小于8的所有值
System.out.println();
printVals(数字,x->x%2==1);//所有奇数值
}
//中间谓词函数
公共静态无效打印val(列表val,谓词
条件){
for(整数v:val){
if(condition.test(v))//如果为true,则打印v
系统输出打印(v+“”);
}
}
}
请注意,我必须使用一个“中间函数”,它利用谓词函数接口的“test()”方法。 但是,如果我决定在使用流时执行类似的操作,我也不必导入java.util.function.Predicate或java.util.stream,也不必在类声明中实现谓词接口。此外,我可以在流中使用谓词Lambda,而无需创建中间函数!为什么呢

public class Using_Predicate {
    public static List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

    public static void main(String[] args) {
        // passing the numbers List and different Lambdas to the intermediate
        // function.
        System.out.println();
        printVals(numbers, x -> x > 6); // all values greater than 6
        System.out.println();
        printVals(numbers, x -> x % 2 == 0); // all even values
        System.out.println();
        printVals(numbers, x -> x < 8); // ll values less than 8
        System.out.println();
        printVals(numbers, x -> x % 2 == 1); // all odd values
    }

    //intermediate Predicate function
    public static void printVals(List<Integer> val, Predicate<Integer>
            condition) {
        for (Integer v : val) {
            if (condition.test(v)) // if true, print v
                System.out.print(v + " ");
        }
    }
}
例如:

// a predicate lambda that prints the first value greater than 3, in this case 5
public class Sample1 {
    public static void main(String[] args) {
        List<Integer> values = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);

        System.out.println(
                values.stream()
                        .filter(e -> e > 3)
                        .findFirst()
        );
    }
}
//输出第一个大于3的值的谓词lambda,在本例中为5
公共类样本1{
公共静态void main(字符串[]args){
列表值=数组.asList(1,2,3,5,4,6,7,8,9,10);
System.out.println(
values.stream()
.过滤器(e->e>3)
.findFirst()
);
}
}

因此,对于lambda和streams规则的“为什么”我真的很困惑,但对于“如何”我就不太清楚了。

导入主要用于不必编写类的完整包名。因此,在这种情况下,如果在代码中的某个地方使用单词
Predicate
,则需要导入
Predicate
。例如,如果必须使用单词
谓词
,而是写出完整的包名
java.util.function.Predicate
,则不需要包含导入


导入不用于为代码提供该类的公共API。因此,您不需要导入
谓词
来为
谓词
创建lambda。编译器已经知道
过滤器
方法引用了哪个
谓词
类。

对您来说,这是一个
谓词
,而不是编译器。如果我们只写这个:

x -> x > 6
这是一个
谓词
,对吗?但是为什么不同时使用
函数

Function<Integer, Boolean> func = x -> x > 6;
函数func=x->x>6;
或者其他适合这里的类型


这也与lambda表达式本身不是内置的(逻辑上类似于
enum
——它只是一些复杂的糖分)有关,并且由于这里没有直接使用
谓词
,编译器推断这是一个
谓词

要搜索的关键字是函数接口

每个只需要实现一个方法(默认方法实现被认为已经实现)的接口都是一个功能接口,可以用lambda表示法或Java8中相应的方法引用来替代

Java 8为常见任务提供了一系列预定义的功能接口(
操作
函数
谓词
使用者
,等等),流API利用了这些接口

例如,
filter()
方法接受一个谓词,它是一个函数接口。因此,您可以将其编写为lambda表达式或方法引用,该方法接受单个参数并返回布尔值。typeparameter T可以从流中上一步返回值的类型推断出来

其余部分的工作方式与Java中的其他地方类似:如果不在类中显式使用类的符号名,则不需要导入它,即使您的类调用了接受并返回另一个类的方法


将函数接口的实现想象成类似于匿名类的东西,只是更轻量级,语法更短。

我也没有在类声明中实现谓词接口,但事实上你已经实现了。lambda是这个接口的实现。你有没有研究过这个?几乎每一个教程和这里的许多答案都涉及到这个问题。如果你在源代码中的任何地方都没有使用谓词符号,为什么你需要导入它?自Java0以来就是这样。例如,
System.out.println(Arrays.asList(1,2,3))
使用一个PrintStream和一个列表,不需要导入PrintStream或List。导入只需要能够使用简单的名称
Foo
,而不是完全限定的名称
com.mycompany.Foo
.FacePalm!是的,如果我使用完全限定名,为什么要导入。但我从不使用完全限定的名称,是吗?我只是创建了一个中间函数,并调用test()。。。对于流示例,我只是使用了一个“谓词样式”lambda。。。。。我肯定我错过了这里所有的树木,所以要耐心