Java 8 릴리스는 2004년 Java 5가 출시된 이후 가장 혁신적인 버전입니다. Java 8은 Java 언어, 컴파일러, 클래스 라이브러리, 개발 도구 및 JVM에 많은 새로운 기능을 제공합니다.
이 기사에서는 Java 1.8의 몇 가지 새로운 기능을 자세히 소개합니다. 이 기사가 도움이 되기를 바랍니다.
1. 람다 표현식
형식: (매개변수) -> {코드 세그먼트}
예: new Thread(() -> {System.out.println("hello world!")}).start (); 이것은 람다 표현식입니다.
람다 구현은 기능적 인터페이스에 의존해야 합니다. Lambda는 본질적으로 익명 내부 클래스입니다. 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(); }
기능적 인터페이스: 하나의 추상 메서드만 있는 인터페이스를 기능적 인터페이스라고 합니다.
기능적 인터페이스 Function, Predicate, Supply, Consumer의 공통 인터페이스는 모두 java.util.function 패키지에 있습니다
Function 인터페이스: 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 인터페이스: 부울 테스트(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)는 매개변수를 받고 어떤 값도 반환하지 않습니다.
생산자-소비자 모델의 생산자는 소비에만 관심이 있습니다. object
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 video tutorial)
람다의 실제 사용법:
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. 메소드 참조:
메소드 참조는 람다 표현식에 메소드 호출이 하나만 있다는 뜻이며, 이 메소드는 이 때 람다 표현식을 메서드 참조로 바꿀 수 있습니다.
메서드 참조에는 네 가지 유형이 있습니다.
클래스 이름::정적 메서드 이름
객체 이름::인스턴스 메서드 이름
클래스 이름::인스턴스 메서드 이름
클래스 이름::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 중국어 웹사이트의 기타 관련 기사를 참조하세요!