Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 理解函数运算符:Lambda_Java_String_Arraylist_Lambda - Fatal编程技术网

Java 理解函数运算符:Lambda

Java 理解函数运算符:Lambda,java,string,arraylist,lambda,Java,String,Arraylist,Lambda,我有一个叫做学期对象学期的数组列表 private ArrayList<Semester> Semesters 然后我得到了一个关于netbeans的提示,上面的所有代码都可以这样写在一行中: String report = year + "\n"; report = Semesters.stream().map((s) -> s.toString() + "\n").reduce(report, String::concat); 我是一名java中级学生,我正在努力理解这

我有一个叫做学期对象学期的数组列表

private ArrayList<Semester> Semesters
然后我得到了一个关于netbeans的提示,上面的所有代码都可以这样写在一行中:

String report = year + "\n";
report = Semesters.stream().map((s) -> s.toString() + "\n").reduce(report, String::concat);
我是一名java中级学生,我正在努力理解这个特性,我发现它非常有用,但我不能完全理解它


请帮助我理解这两段代码是如何相同的

我没有使用Java lambdas,但是通过函数式编程范例中的
map
reduce\fold
操作,这两个代码片段是如何等效的:

  • map
    基本上将特定函数应用于集合中的每个元素。在本例中,该函数/方法是
    s.toString()+“\n”
    。这与迭代集合并通过foreach循环将函数应用于每个元素是一样的
  • reduce
    是一种折叠操作,即它将map操作返回的每个元素连接到原始字符串
    report
  • 所以在你的原始代码中

    String report = year + "\n";
    for (Semester s : Semesters) {
        report += s.toString() + "\n";
    }
    
    基本上是对元素
    s
    进行操作,然后将该操作的结果连接到
    report
    。使用lambda,首先在
    map
    阶段对整个集合进行操作,然后遍历映射期间返回的集合,并在
    reduce
    阶段将每个元素连接到
    report

    • semests.stream()
      将一次性提供一个
      stream
      对象(像迭代器一样有状态)
    • .map(…)
      提供了一个函数接口:一个只有一个参数类型为的方法的接口
    • lambda表达式将生成一个生成接口的实例,该接口包含一个方法,该方法的参数和字符串为结果类型
    • 因此,map生成一条流
    • Map稍后将迭代整个学期,应用该方法并收集字符串
    • Stream.reduce(String startValue,stepFunction)
      将允许操作(迭代)在每个步骤上开始收集单个字符串,初始化为startValue:`result=result.concat(map方法的返回值)
    我希望我的解释是对的

    System.out.println("Mapping Semester to String...");
    Stream<String> sems = Semesters.stream().map((s) -> {
            System.out.println("map call " + s);
            return s + "\n";
        });
    System.out.println("Reducing String stream to String...");
    String report = sems.reduce(year + "\n", String::concat);
    

    以下是使用匿名类分解的等效功能:

    Function<Semester, String> toStrFn = new Function<Semester, String>() {
      @Override
      public String apply(Semester semester) {
        return semester + "\n";
      }
    };
    
    BinaryOperator<String> reducer = new BinaryOperator<String>() {
      @Override
      public String apply(String lastResult, String currentValue) {
        return lastResult.concat(currentValue);
      }
    };
    
    String report = year + "\n";
    Stream<Semester> semesterStream = Semesters.stream();
    Stream<String> stringStream = semesterStream.map(toStrFn);
    report = stringStream.reduce(report, reducer);
    
    函数toStrFn=新函数(){
    @凌驾
    公共字符串应用(学期){
    返回学期+“\n”;
    }
    };
    BinaryOperator reducer=新的BinaryOperator(){
    @凌驾
    公共字符串应用(字符串lastResult、字符串currentValue){
    返回lastResult.concat(当前值);
    }
    };
    字符串报告=年+“\n”;
    Stream semesterStream=学期。Stream();
    Stream stringStream=semestrestream.map(toStrFn);
    report=stringStream.reduce(report,reducer);
    
    String report = year + "\n"
        + semesters.stream()
            .filter(...)
            .sorted(...)
            .map(Semester::toString)
            .collect(Collectors.joining("\n"));
    
    Function<Semester, String> toStrFn = new Function<Semester, String>() {
      @Override
      public String apply(Semester semester) {
        return semester + "\n";
      }
    };
    
    BinaryOperator<String> reducer = new BinaryOperator<String>() {
      @Override
      public String apply(String lastResult, String currentValue) {
        return lastResult.concat(currentValue);
      }
    };
    
    String report = year + "\n";
    Stream<Semester> semesterStream = Semesters.stream();
    Stream<String> stringStream = semesterStream.map(toStrFn);
    report = stringStream.reduce(report, reducer);