前言:
现时兄弟们对“java filereader读取文件”可能比较着重,大家都想要了解一些“java filereader读取文件”的相关内容。那么小编也在网上搜集了一些关于“java filereader读取文件””的相关内容,希望看官们能喜欢,各位老铁们快快来了解一下吧!笔者对函数编程、匿名函数、lamda一直都不感冒。个人认为代码看起来简单了,但是会提高代码的理解性难度,尤其代码在未来需要扩展,容易造成不可扩展,因为函数编程本来也强调了不可变性。
不过存在即合理,并且官方也推荐,一定存在高价值性。不喜欢,可以不用,但是相关知识还是需要知晓。
函数编程、匿名函数和Lambda表达式概念。函数编程(Functional Programming): 函数编程是一种编程范式,它将计算过程看作是函数之间的转换。函数是函数编程的核心概念,它们可以像数据一样传递、组合和操作。函数编程强调纯函数的使用,即函数的输出只依赖于输入,没有副作用和可变状态的影响。函数编程还倡导将函数作为一等公民,可以将函数赋值给变量、作为参数传递给其他函数以及作为返回值返回。匿名函数(Anonymous Function): 匿名函数是一种不需要命名的函数,可以直接在需要的地方定义和使用,而不必为其指定一个独立的名称。匿名函数通常用于需要传递函数作为参数或赋值给变量的场景,避免了显式地定义命名函数的过程。在函数式编程中,匿名函数常常用于实现高阶函数,即函数接受一个或多个函数作为参数或返回一个函数。Lambda表达式: Lambda表达式是一种轻量级的匿名函数语法,它允许我们以更简洁、更易读的方式编写匿名函数。Lambda表达式是函数式编程的一个重要特性,它可以用来替代冗长的匿名内部类。Lambda表达式可以作为参数传递给函数或方法,或者赋值给一个函数式接口变量。它的语法形式为(parameters) -> expression或(parameters) -> { statements; },其中parameters是参数列表,expression是表达式或语句块。函数式编程的几个核心概念和特点函数传递:函数可以像任何其他数据类型一样被传递给其他函数,可以被赋值给变量,可以存储在数据结构中,也可以作为函数的返回值。纯函数(Pure Functions):纯函数是指对于相同的输入,总是产生相同的输出,并且没有任何可观察的副作用。纯函数不依赖于外部状态,不修改传入的参数,也不引起系统状态的变化。不可变性(Immutability):函数式编程鼓励使用不可变数据结构,即一旦创建就不能修改的数据结构。因为不可变性可以减少状态变化的复杂性,避免竞态条件和并发问题。引用透明(Referential Transparency):引用透明意味着可以将函数调用替换为函数返回的结果,而不会影响程序的行为。这种特性使得代码更易于理解、测试和推理。高阶函数(Higher-Order Functions):高阶函数是指可以接受一个或多个函数作为参数,并且/或者返回一个函数的函数。高阶函数使得代码更加抽象和灵活,可以进行函数的组合、变换和延迟执行等操作。声明式编程(Declarative Programming):函数式编程更加强调声明式的编程风格,即关注“做什么”而不是“怎么做”。通过将计算过程抽象为函数调用和组合,减少了显式的控制流和状态管理。
在函数式编程中,常用的函数操作包括映射(map)、过滤(filter)、折叠(reduce)等。此外,函数式编程还经常使用递归、柯里化、惰性求值等技术来处理问题。
匿名函数和Lambda表达式
匿名函数是一种不需要命名的函数,可以直接在需要的地方定义和使用,而不必为其指定一个独立的名称。它通常用于需要传递函数作为参数或赋值给变量的场景,避免了显式地定义命名函数的过程。
匿名函数的优点在于它简化了代码的结构,减少了冗余的定义和命名过程。它使得代码更加紧凑,更易于理解和阅读。匿名函数常用于函数式编程、事件处理、回调函数等场景。
在许多编程语言中,匿名函数的语法形式通常是使用关键字或特殊符号来表示匿名函数的开始和结束,并提供参数列表和函数体。
在Java中,Lambda表达式是一种匿名函数的形式。它的语法形式为(parameters) -> expression或(parameters) -> { statements; },其中parameters是参数列表,expression是单个表达式或者{ statements; }是多条语句组成的函数体。
以下是一个简单的Java Lambda表达式的示例:
Runnable runnable = () -> { System.out.println("This is an example of an anonymous function."); System.out.println("It is defined using a Lambda expression.");};
在上述示例中,我们使用Lambda表达式创建了一个匿名函数,并将其赋值给一个Runnable接口变量。Lambda表达式的函数体包含了两条打印语句。
Lambda表达式:
(parameters) -> expression或(parameters) -> { statements; }
其中,parameters是参数列表,expression是表达式或语句块。
Lambda表达式省略了方法的名称和返回类型,只关注参数和执行逻辑。它可以用来替代匿名内部类,并且更加简洁和易读。
下面是一个使用Lambda表达式的匿名函数的示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");names.forEach(name -> System.out.println(name));
示例中使用forEach方法和Lambda表达式遍历打印names列表中的每个元素。Lambda表达式name -> System.out.println(name)代表一个接受一个参数并执行打印操作的匿名函数。
Lambda表达式使用场景函数式接口:Lambda表达式适用于函数式接口,即只有一个抽象方法的接口。在这种情况下,可以使用Lambda表达式作为接口的实现。集合操作:Lambda表达式可以方便地应用于集合操作,如筛选、映射、排序等。通过使用Lambda表达式,可以以一种简洁、清晰的方式对集合中的元素进行处理和操作。并行处理:Lambda表达式与Java 8引入的Stream API结合使用,可以方便地进行并行处理。通过将任务分解为多个子任务并并行处理,可以提高代码的性能。事件监听器:Lambda表达式可以简化事件监听器的实现。通过将Lambda表达式作为事件处理器,可以更直观地表达事件的处理逻辑,而无需显式地编写匿名内部类。线程和并发编程:Lambda表达式可以用于简化线程和并发编程。通过将任务封装为Lambda表达式,可以更方便地实现多线程和并发操作。表达式求值:Lambda表达式可以用于实现动态表达式求值,比如在计算器应用中解析和计算表达式。Lambda表达式例子:数据转换和处理:使用函数式编程可以轻松地对数据进行转换和处理。例如,使用map操作可以对集合中的每个元素应用同一个函数,将其转换为新的元素。这种数据转换非常适合函数式编程的风格。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);List<Integer> doubledNumbers = numbers.stream() .map(n -> n * 2) .collect(Collectors.toList());
在上述示例中,使用map操作将列表中的每个元素都乘以2,并收集到一个新的列表中。
过滤和筛选:函数式编程非常适合对数据进行过滤和筛选的场景。使用filter操作可以根据某个条件过滤出满足条件的元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList());
在上述示例中,使用filter操作筛选出列表中的偶数。
并行处理:函数式编程鼓励无副作用和不可变性的特性,使得代码更容易进行并行处理。通过使用并行流,可以将计算任务分配给多个处理器核心并行执行,提高处理效率。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);int sum = numbers.parallelStream() .mapToInt(Integer::intValue) .sum();
在上述示例中,使用并行流对列表中的数字进行求和操作,可以在多个处理器核心上并行执行。
延迟执行:函数式编程支持延迟执行的特性,只有在需要结果时才进行实际的计算。这种特性可以提高性能,避免不必要的计算。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);Stream<Integer> doubledNumbers = numbers.stream() .map(n -> n * 2);// 省略其他操作int sum = doubledNumbers.reduce(0, Integer::sum);
在上述示例中,map操作会生成一个延迟执行的Stream,只有在调用reduce操作时才会进行实际的计算。
Stream、filter和collect是Java中的函数式编程特性和API,属于java.util.stream包。
Stream是Java 8引入的一个用于处理集合数据的API。它提供了一种流式处理数据的方式,可以进行转换、过滤、映射、排序等操作。Stream API提供了丰富的方法来处理数据流,如map、filter、reduce等,使得代码更加简洁和易读。filter是Stream接口中的一个中间操作方法,用于过滤流中的元素。它接受一个Predicate函数式接口作为参数,用于判断元素是否满足条件。只有满足条件的元素会被保留下来,组成一个新的流。collect是Stream接口中的一个终止操作方法,用于将流中的元素收集到一个集合或其他数据结构中。它接受一个Collector参数,用于定义收集的方式。常见的收集器包括Collectors.toList()、Collectors.toSet()等,用于将元素收集到List或Set中。
这些函数式编程的方法和API使得在Java中进行集合数据处理变得更加方便和灵活。它们属于Java标准库中的java.util.stream包,提供了丰富的功能和操作,帮助我们更好地处理和转换集合数据。扩展下,数据类型有stream()方法的类型,它们具有stream()方法:
集合类(Collections):List 接口的实现类(如 ArrayList、LinkedList)Set 接口的实现类(如 HashSet、LinkedHashSet)Queue 接口的实现类(如 ArrayDeque、LinkedList)数组(Array):通过Arrays.stream()方法可以将数组转换为流。Map 接口的实现类:Map 接口的实现类(如 HashMap、TreeMap)ConcurrentMap 接口的实现类(如 ConcurrentHashMap)IO 流(IO Streams):java.io.BufferedReader、java.io.FileReader 等读取文件的类字符串(String):String 类提供了chars()、codePoints()等方法来创建字符流。更具体的例子:
假设我们有一个包含一组人员的列表,我们希望从中筛选出年龄大于等于18岁的成年人,并将他们的姓名收集到一个新的列表中。
import java.util.Arrays;import java.util.List;import java.util.stream.Collectors;public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 25), new Person("Bob", 17), new Person("Charlie", 30), new Person("David", 20) ); List<String> adultNames = people.stream() .filter(person -> person.getAge() >= 18) .map(Person::getName) .collect(Collectors.toList()); System.out.println(adultNames); // 输出: [Alice, Charlie, David] }}
在上述例子中,创建了一个Person类来表示人员,包含姓名和年龄属性。
通过使用Stream,可以将people列表转换为一个数据流。然后,使用filter方法筛选出年龄大于等于18岁的成年人,即满足条件 person -> person.getAge() >= 18 的人。
接下来,我们使用map方法将每个成年人的姓名映射为一个新的流。Person::getName 是一个方法引用,表示使用Person对象的getName方法来获取姓名。
最后,使用collect方法将流中的姓名收集到一个新的列表中,使用Collectors.toList()收集器来创建一个List对象。
最终,打印输出了筛选出的成年人的姓名列表 [Alice, Charlie, David]。
通过这个例子,可以看到使用Stream、filter和collect的过程:首先,使用Stream将数据转换为流;然后使用filter对流中的元素进行筛选;接着使用map对流中的元素进行映射;最后使用collect将流中的元素收集到一个新的集合中。
这种函数式编程的方式使得代码更加简洁、可读性更高,并且提供了一种声明式的方式来处理集合数据(更加简洁、可读性更高是官方说法,我是不认同的。那天我突然想改下逻辑,那一坨代码我就要全部改,同时又担心改了会不会改到其他人最先设定的一些其他逻辑,头疼与纠结)。
标签: #java filereader读取文件