ホームページ  >  記事  >  Java  >  Java 1.8の新機能の事前学習

Java 1.8の新機能の事前学習

王林
王林転載
2021-02-26 10:06:463406ブラウズ

Java 1.8の新機能の事前学習

Java 8 リリースは、2004 年にリリースされた Java 5 以来最も革新的なバージョンです。 Java 8 は、Java 言語、コンパイラ、クラス ライブラリ、開発ツール、JVM に多くの新機能をもたらします。

この記事では、皆様のお役に立つことを願って、Java 1.8 のいくつかの新機能を詳しく紹介します。

1. ラムダ式

形式: (パラメータ) -> {コード セグメント}

例: new Thread(() -> {System.out. println("hello world!")}).start(); これはラムダ式です。

ラムダの実装は関数型インターフェイスに依存する必要があります。ラムダは本質的に匿名内部クラスです。jdk1.8 より前では、メソッドが他のインターフェイスの実装メソッドを操作する必要がある場合、匿名内部クラスを通じて実現できます。

jdk1.8 以降では、匿名内部クラスをラムダ式に置き換えることができ、より簡素化されています。

package java8;
 
public class LambdaDemo {
	
	public static void main(String[] args) {
		//JDK1.8之前使用接口,采用匿名内部类的方式
		MyInterface mi = new MyInterface() {
			@Override
			public void test() {
				System.out.println("test");
			}
		};
		
		mi.test();
		
		//JDK1.8之后,使用lambda表达式
		MyInterface lmi = () -> {
			System.out.println("test");
		};
		
		lmi.test();
	}
}
//定义一个函数式接口,只有一个抽象方法 
interface MyInterface{
	
	void test();
}

関数型インターフェイス: 抽象メソッドが 1 つだけあるインターフェイスは関数型インターフェイスと呼ばれます

関数型インターフェイスの共通インターフェイスである Function、Predicate、Supplier、Consumer はすべて Java にあります。 .util. ​​

関数パッケージの関数インターフェイス: R apply(T t) パラメーターを受け取り、オブジェクトを返します。

package java8;
 
import java.util.function.Function;
 
public class LambdaDemo {
 
	public static void main(String[] args) {
		// function的使用
		// 传统模式,第一个泛型:接收的参数类型 第二个泛型,返回的参数类型
		Function<String, String> function1 = new Function<String, String>() {
			@Override
			public String apply(String t) {
				return t;
			}
		};
		// 调用apply方法,并获取返回结果
		String res1 = function1.apply("function的使用");
		System.out.println(res1);
		// lambda的使用,当参数只有一个且不写参数类型时,"()"可以省略
		Function<String, String> function2 = t -> {
			return t;
		};
		// 调用apply方法,并获取返回结果
		String res2 = function2.apply("function的使用");
		System.out.println(res2);
	}
}

Predicate インターフェイス: boolean test(T t) パラメーターを受け取り、オブジェクトを返します。ブール値

一般的に比較に使用されます

package java8;
 
import java.util.function.*;
 
public class LambdaDemo {
 
	public static void main(String[] args) {
		// predicate的使用
		// 传统模式,泛型参数:接收的参数类型
		Predicate<Integer> predicate1 = new Predicate<Integer>() {
 
			@Override
			public boolean test(Integer t) {
				// 大于等于10就为真,否则为假
				return t >= 10;
			}
 
		};
		// 执行predicate1的方法
		System.out.println(predicate1.test(11));
		System.out.println(predicate1.test(8));
		
		
		//使用lambda表达式
		Predicate<Integer> predicate2 = new Predicate<Integer>() {
			@Override
			public boolean test(Integer t) {
				// 大于等于10就为真,否则为假
				return t >= 10;
			}
		};
		// 执行predicate1的方法
		System.out.println(predicate2.test(11));
		System.out.println(predicate2.test(8));
	}
}

サプライヤー インターフェイス: T get() はオブジェクトを返します

プロデューサー/コンシューマー モデルのプロデューサーはオブジェクトのみを生成します

package java8;
 
import java.util.function.*;
 
public class LambdaDemo {
 
	public static void main(String[] args) {
		//Supplier的使用
		// 传统模式,泛型参数:返回的参数类型
		Supplier<String> s1 = new Supplier<String>() {
 
			@Override
			public String get() {
				return new String("supplier");
			}
		};
		//调用
		System.out.println(s1.get());
		
		// 使用lambda表达式
		//当代码只有一句时,可以省略"{}",不接收参数时,"()"不能省略
		Supplier<String> s2 = () -> new String("supplier");
		System.out.println(s2.get());
	}
}

コンシューマ インターフェイス: accept (T t) はパラメータを受け取り、値を返しません。

プロデューサー/コンシューマ モデルのプロデューサーはオブジェクトのみを消費します。

package java8;
 
import java.util.function.*;
 
public class LambdaDemo {
 
	public static void main(String[] args) {
		// Consumer的使用
		// 传统模式,泛型参数:返回的参数类型
		Consumer<String> con1 = new Consumer<String>() {
 
			@Override
			public void accept(String t) {
				System.out.println(t);
			}
		};
		con1.accept("consumer");
		
		//使用lambda表达式,同时省略"()","{}"
		Consumer<String> con2 = t -> System.out.println(t);
		con2.accept("consumer");
	}
}

(学習ビデオ共有:java ビデオ チュートリアル )

ラムダの実際の使用法:

package java8;
 
import java.util.function.*;
 
public class LambdaDemo {
 
	public static void main(String[] args) {
		//Runnable的实现,
		new Thread(() -> {
			System.out.println(Thread.currentThread().getName() + " run");
		}).start();
		
		System.out.println(Thread.currentThread().getName() + " run");
	}
}

2. メソッド参照:

メソッド参照とは、メソッド呼び出しが 1 つだけであることを意味します。ラムダ式とこのメソッドが実際に存在する場合は、ラムダ式をメソッド参照に置き換えることができます。

メソッド参照には 4 種類あります

クラス名::静的メソッド名

オブジェクト名::インスタンス メソッド名

クラス名::インスタンスメソッド名

クラス名::new

package java8;
 
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
 
public class MethodReferenceDemo {
	public static void main(String[] args) {
		// 定义3个Student对象
		Student s1 = new Student("zhangsan", 90);
		Student s2 = new Student("lisi", 60);
		Student s3 = new Student("wangwu", 70);
		// 添加到集合
		List<Student> students = Arrays.asList(s1, s2, s3);
 
		//普通的lambda实现
		// sort接收两个参数,第一个参数,要排序的集合,第二个参数,Comparator接口的实现
		// Collections.sort(students, (stu1,stu2) -> StudentSortUtil.sortByScore(stu1,stu2));
		// students.forEach(t -> System.out.println(t.getScore()));
 
		// 方法引用1---类名::静态方法名
		// Collections.sort(students, StudentSortUtil::sortByScore);
		// students.forEach(t -> System.out.println(t.getScore()));
		
		//创建实例对象,调用实例对象的方法
		StudentSortUtil ssu = new StudentSortUtil();
		
		//普通的lambda实现
//		Collections.sort(students, (stu1, stu2) -> ssu.sortByScoreInstance(stu1, stu2));
//		students.forEach(t -> System.out.println(t.getScore()));
		
		// 方法引用2---对象名::实例方法名
//		Collections.sort(students, ssu::sortByScoreInstance);
//		students.forEach(t -> System.out.println(t.getScore()));
		
		/*
		 * 方法引用3---类名::实例方法名
		 * Student的sortByScore()只有一个参数,而Comparator的实现需要两个参数,为什么编译器不报错?
		 * 这是因为sortByScore是一个普通方法,要使用这个方法肯定要有一个Student类的实例对象来调用
		 * 而调用的这个方法的对象就作为Comparator的第一个参数对象传递进来
		 * 例String的compareTo()方法,调用这个方法首先要有一个String的实例对象,
		 * 此处str就是这个实例对象,str就作为Comparator的第一个参数
		 * "hello"这个String对象就作为第二个参数
		 * String str = new String("str1");
		 * str.compareTo("hello");	
		 */
		Collections.sort(students, Student::sortByScore);
		
		
		//创建一个新的Student对象,使用lambda表达式创建
		//不接收参数,返回一个对象,其实就是Supplier接口的实例
		Supplier<Student> su1 = () -> new Student();
		//方法引用4---类名::new
		Supplier<Student> su2 = Student::new;
		
		//BiConsumer是Consumer的扩展,可以接受两个参数返回一个值
		BiConsumer<String, Integer> bc1 = (name,score) -> new Student(name,score);
		//替换上面的lambda表达式,需要接收两个参数,所以调用的是有参构造方法
		BiConsumer<String, Integer> bc2 = Student::new;
		
	}
}
 
//定义一个学生实体类
class Student {
	private String name;
	private int score;
 
	public Student() {
	}
 
	public Student(String name, int score) {
		this.name = name;
		this.score = score;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public int getScore() {
		return score;
	}
 
	public void setScore(int score) {
		this.score = score;
	}
 
	public int sortByScore(Student stu) {
		return this.getScore() - stu.getScore();
	}
 
	public int sortByName(Student stu) {
		return this.getName().compareTo(stu.getName());
	}
}
 
//定义一个学生排序工具类
class StudentSortUtil {
 
	public static int sortByScore(Student stu1, Student stu2) {
		return stu1.getScore() - stu2.getScore();
	}
 
	public static int sortByName(Student stu1, Student stu2) {
		return stu1.getName().compareTo(stu2.getName());
	}
 
	// 普通方法,创建对象才能调用
	public int sortByScoreInstance(Student stu1, Student stu2) {
		return stu1.getScore() - stu2.getScore();
	}
 
	// 普通方法,创建对象才能调用
	public int sortByNameInstance(Student stu1, Student stu2) {
		return stu1.getName().compareTo(stu2.getName());
	}
}

3. ストリーム:

ストリームは中間操作と終了操作に分かれており、中間操作は引き続き新しいストリームを返しますおよび終了操作 結果を返します。

コード行に中間操作のみがある場合、その操作は実行されず、終了操作が発生した場合にのみ実行されます。

package java8;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.stream.Stream;
 
public class StreamDemo {
	
	public static void main(String[] args) {
		//Stream的使用
		
		//创建流,参数为可变参数
		Stream<Integer> stream = Stream.of(50,66,88);
		
		//将Stream转化为数组
		//Object[] array =  stream.toArray();
		//System.out.println(Arrays.toString(array));
		
		//筛选过滤条件,参数为Predicate,动作自己指定,找到大于60的数
		//流分为中间操作和终止操作,节点流会继续返回一个流对象,终止操作会返回一个结果,
		//只有中间流,代码不会执行,只有遇见终止操作才会执行
		//stream.filter((target) -> target > 60).forEach(System.out::println);
		
		//map对数据进行操作,接收一个Function实例 例:对流中的每个元素都乘以2
		stream.map((t) -> 2 * t).forEach(System.out::println);
		
		//流的无限模式,会对seed一直执行UnaryOperator的事件,一般和limit配合使用
		//skip(n)跳过n个元素,limit(n) 返回n个元素的流
		Stream.iterate(0, t -> t + 2).skip(2).limit(6).forEach(System.out::println);
		
		//将流转换为集合对象,第一个参数,传递一个Supplier 最终结果类型由此提供
		//第二个参数 BiConsumer() 传递两个参数,第一个要操作的集合,第二个当前的流元素
		//第三个元素BiConsumer() 传递两个集合,最终合并成一个集合
		//类似StringBuffer.append()方法
//		stream.collect(() -> new ArrayList<Integer>(),
//				(target,item)-> target.add(item),
//				(result,target)-> result.addAll(target)).forEach(System.out::println);
		//可以使用方法引用简化
		stream.collect(LinkedList::new,LinkedList::add,LinkedList::addAll);
		
	}
}

関連する推奨事項: Java 入門チュートリアル

以上がJava 1.8の新機能の事前学習の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。