Java 8 新特性之 Lambda表达式

简介: Lambda的出现就是为了增强Java面向过程编程的深度和灵活性。今天就来分享一下在Java中经常使用到的几个示例,通过对比分析,效果应该会更好。–1、实现Runnable线程案例其存在的意义就是用Lambda来代替匿名类,如下:// before java 8...

Lambda的出现就是为了增强Java面向过程编程的深度和灵活性。今天就来分享一下在Java中经常使用到的几个示例,通过对比分析,效果应该会更好。

1、实现Runnable线程案例

其存在的意义就是用Lambda来代替匿名类,如下:

// before java 8
new Thread(new Runnable(){
@Override
public void run(){
    System.out.println("Before Java 8");
}
}

// Java 8 way
new Thread(()-> System.out.println("Java 8 Way"););

我们可以使用下面的语法来完成Lambda的书写:

  • (params) -> expression
  • (params) -> statement
  • (params) -> {statements}
    如果表达式不需要参数,那么可以简写如下:
    () -> Ssytem.out.println("Something Here!");

2、实现事件处理

这里拿Swing编程来举例,主要的作用是简化事件监听器的代码书写。

// Before java 8
JButton button = new JButton("Show");
button.addActionListener(new ActionListener(){

    @Override
    public void actionPerformed(ActionEvent e){
        System.ut.println("Before Java 8");
    }
});

// Java 8 Way
button.addActionListener((e)-> {
    System.out.println("Java 8 Way");
};

不难看出,使用Lambda来代替匿名类是一件很优雅的事情。

3、使用Lambda表达式遍历List集合

遍历输出一个集合是一件很简单但是很繁琐的事情,但是有了Lambda之后,一切。又将变的优雅起来。

// Before Java 8
List ls = Arrays.asList("Lambdas","Default Method","Stream API","Date and Time Api");

for(String item : ls){
    System.out.println(item);
}

// Java 8 Way
List ls = Arrays.asList("Lambdas","Default Method","Stream API","Date and Time Api");
// 这里很重要,因为输出语句后面没有那个分号!!!
ls.forEach(item -> System.out.println(item));

4、使用Lambda表达式和函数接口

为了使得Java支持函数编程,Java8 加入了一个新的包java.util.function,其中有一个接口java.util.function.Predicate 是支持Lambda函数编程。

@Test
    public void test6() throws Exception {
        List<String> languages = Arrays.asList("C", "C++", "Java", "HTML", "CSS", "JavaScript", "C#", "MySQL");
        List<String> result = languages.stream().filter(item -> item.startsWith("J")).collect(Collectors.toList());
        System.out.println(languages.toString());
        System.out.println("---------------co" + "mpared result--------------");
        System.out.println("With J:");
        System.out.println(result.toString());
    }

上面的filter(item -> item.startWith(“J”))就是对此接口的简单的使用,这便是因为Lambda支持接口调用的体现。

详细的操作方式,我们可以参考Stream API来进行更加复杂的操作。

5、较复杂的结合Predicate接口的使用

此处主要演示的是结合流操作,类似于Linux的管道命令。

Predicate<String> startsWithJ = (n) -> n.startsWith("J");
 Predicate<String> fourLetterLong = (n) -> n.length() == 4;

 names.stream()
      .filter(startsWithJ.and(fourLetterLong))
      .forEach((n) -> System.out.print("\nName, which starts with
            'J' and four letter long is : " + n));

在流操作的整个过程中,StreamAPI内使用的就是我们定义好的Predicate实现。是不是感觉很方便啦。

6、使用Lambda实现Map和Reduce

  • 类比Python中的可变数组,Java8 的Map就是实现了类似的功能。我们可以方便的借助Lambda来实现元素信息的改变。
// Before Java 8
List costBeforeTax = Arrays.asList(100,200,300,400,500);
for(Integer cost: costBeforeTax){
    double price = cost+.12*cost;
    System.out.println(price);
}

// Java 8 Way
List costBeforeTax = Arrays.asList(100,200,300,40,500);
costBeforeTax.stream().map((cost)-> cost+.12*cost).forEach(System.out.println(cost));
  • reduce() 是将集合中所有的值结合,汇聚到一个值中,Reduce类似SQL语句中的sum(),avg(),count()等等。
// Applying 12% VAT on each purchase
// Old way:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double total = 0;
for (Integer cost : costBeforeTax) {
 double price = cost + .12*cost;
 total = total + price;

}
System.out.println("Total : " + total);

// New way:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost)
                                    .reduce((sum, cost) -> sum + cost)
                                    .get();
System.out.println("Total : " + bill);

Output
Total : 1680.0
Total : 1680.0

7.通过filtering 创建一个字符串String的集合

Filtering是对大型Collection操作的一个通用操作,Stream提供filter()方法,接受一个Predicate对象,意味着你能传送lambda表达式作为一个过滤逻辑进入这个方法:

// Create a List with String more than 2 characters
List<String> filtered = strList.stream().filter(x -> x.length()> 2)
                                        .collect(Collectors.toList());
System.out.printf("Original List : %s, filtered list : %s %n", 
                  strList, filtered);

Output :
Original List : [abc, , bcd, , defg, jk], filtered list : [abc, bcd, defg]

8、对集合中的每个元素应用函数

// Convert String to Uppercase and join them using coma
List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", 
                                "Italy", "U.K.","Canada");
String G7Countries = G7.stream().map(x -> x.toUpperCase())
                                .collect(Collectors.joining(", "));
System.out.println(G7Countries);

Output : 
USA, JAPAN, FRANCE, GERMANY, ITALY, U.K., CANADA
上面是将字符串转换为大写,然后使用逗号串起来。

9、通过复制不同的值创建一个子列表

使用Stream的distinct()方法过滤集合中的重复性的元素。

// Create List of square of all distinct numbers
List<Integer> numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4);
List<Integer> distinct = numbers.stream().map( i -> i*i).distinct()
                                         .collect(Collectors.toList());
System.out.printf("Original List : %s,  Square Without duplicates :
                   %s %n", numbers, distinct);

Output :
Original List : [9, 10, 3, 4, 7, 3, 4],  Square Without 
                                         duplicates : [81, 100, 9, 16, 49]

10、计算List中的元素的最大值,最小值,总和以及平均值

@Test
    public void test7() throws Exception {
        List<Integer> ls = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        IntSummaryStatistics stats = ls.stream().mapToInt((x)->x).summaryStatistics();

        System.out.println("Max:"+ stats.getMax());
        System.out.println("Min:"+ stats.getMin());
        System.out.println("Avg:"+ stats.getAverage());
        System.out.println("SUm:"+ stats.getSum());
    }

结语

最后,推荐一个比较好的StreamAPI的介绍网址,里面有很多详细的示例,相信对大家的变成会有很大的帮助。

http://www.journaldev.com/2774/java-8-stream

目录
相关文章
|
2天前
|
并行计算 Java 编译器
Java Lambda表达式简介
Java Lambda表达式简介
9 0
|
4天前
|
Java API
Java Lambda
Java Lambda
13 0
|
4天前
|
Java 开发者
探索 Java 的函数式接口和 Lambda 表达式
【4月更文挑战第19天】Java 中的函数式接口和 Lambda 表达式提供了简洁、灵活的编程方式。函数式接口有且仅有一个抽象方法,用于与 Lambda(一种匿名函数语法)配合,简化代码并增强可读性。Lambda 表达式的优点在于其简洁性和灵活性,常用于事件处理、过滤和排序等场景。使用时注意兼容性和变量作用域,它们能提高代码效率和可维护性。
|
5天前
|
机器学习/深度学习 Java API
Java8中的新特性
Java8中的新特性
|
7天前
|
分布式计算 Java API
Java 8新特性之Lambda表达式与Stream API
【4月更文挑战第16天】本文将介绍Java 8中的两个重要新特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁、易读。Stream API是Java 8中引入的一种新的数据处理方式,它允许我们以声明式的方式处理数据,从而使代码更加简洁、高效。本文将通过实例代码详细讲解这两个新特性的使用方法和优势。
|
11天前
|
安全 算法 Java
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第11天】 在Java中,高效的并发编程是提升应用性能和响应能力的关键。本文将探讨Java并发的核心概念,包括线程安全、锁机制、线程池以及并发集合等,同时提供实用的编程技巧和最佳实践,帮助开发者在保证线程安全的前提下,优化程序性能。我们将通过分析常见的并发问题,如竞态条件、死锁,以及如何利用现代Java并发工具来避免这些问题,从而构建更加健壮和高效的多线程应用程序。
|
4天前
|
安全 Java
深入理解 Java 多线程和并发工具类
【4月更文挑战第19天】本文探讨了Java多线程和并发工具类在实现高性能应用程序中的关键作用。通过继承`Thread`或实现`Runnable`创建线程,利用`Executors`管理线程池,以及使用`Semaphore`、`CountDownLatch`和`CyclicBarrier`进行线程同步。保证线程安全、实现线程协作和性能调优(如设置线程池大小、避免不必要同步)是重要环节。理解并恰当运用这些工具能提升程序效率和可靠性。
|
5天前
|
安全 Java
java多线程(一)(火车售票)
java多线程(一)(火车售票)
|
5天前
|
安全 Java 调度
Java并发编程:深入理解线程与锁
【4月更文挑战第18天】本文探讨了Java中的线程和锁机制,包括线程的创建(通过Thread类、Runnable接口或Callable/Future)及其生命周期。Java提供多种锁机制,如`synchronized`关键字、ReentrantLock和ReadWriteLock,以确保并发访问共享资源的安全。此外,文章还介绍了高级并发工具,如Semaphore(控制并发线程数)、CountDownLatch(线程间等待)和CyclicBarrier(同步多个线程)。掌握这些知识对于编写高效、正确的并发程序至关重要。

热门文章

最新文章