jdk8新特性 forEach方法和方法引用

先说明,jdk8增加了一个包java.util.function,里面存放的都是新增的函数式接口,方便用lambda表达式重写其抽象方法

下面列举三个常见的函数式接口,下行是其抽象方法

 Consumer<T>代表了接受一个输入参数并且无返回的操作

 void accep(T t)接收一个参数,使用它
 IntConsumer接受一个int类型的输入参数,无返回值 。

void accept(int value)接收一个int类型参数,使用它
 Supplier<T>无参数,返回一个结果。

 T get()返回一个T类型的对象

forEach

jdk8在Iterable接口中增加了defalut修饰的forEach()方法,用来遍历

先看下Iterable接口的源码

public interface Iterable<T> {
    Iterator<T> iterator();
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

forEach方法,接收一个Consumer类型的参数action,然后调用增强for循环对容器对象使用action.accept方法

咱们再来看Consumer接口的源码

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);//抽象方法
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

accept为抽象方法,需要重写

到此我们知道怎么使用forEach来遍历集合了

要先调用容器的forEach方法,重写Consumer接口的accept方法

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ForEachTest03 {
	public static void main(String[] args) {
		List<Integer> list = new ArrayList<>();
		list.add(3);
		list.add(5);
		list.add(-1);
		// 使用forEach方法遍历,实验匿名内部类的方式重写Consumer接口的accept方法
		list.forEach(new Consumer<Integer>() {

			@Override
			public void accept(Integer t) {
				System.out.print(t + " ");

			}
		});
		System.out.println();
		// 使用lambda方式重写函数式接口的抽象方法更简洁
		list.forEach((i) -> {
			System.out.print(i + " ");
		});

	}
}
out:
3 5 -1
3 5 -1

方法引用

方法引用指  通过方法的名字来指向一个方法。

方法引用的作用主要是简化lambda表达式,当lambda表达式只执行一个方法时,可使用方法引用简写lambda表达式

语法:  使用两个冒号  ::

有四种情况:

静态方法引用

类名::方法名

某个对象的引用,

对象实例::方法名

构造方法引用

构造方法,类名::new

特定类的任意对象的方法引用,  这个方法引用的使用需要注意,自定义类中无参数的方法可以使用,比如toString,hashCode等,或者compareTo等特定方法也可以使用,还没搞清楚什么原理呢,建议慎用,正常写就好了

类名::方法名

下面来示例:任意对象的方法引用

list.forEach((i)->System.out.println(i));
list.forEach(System.out::println);//System.out 

示例:静态方法的方法引用

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class Test05 {
	public static void main(String[] args) {
		Set<Integer> set1 = new TreeSet<>(new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return Integer.compare(o1, o2);
			}

		});
		Set<Integer> set = new TreeSet<>(Integer::compareTo);
		set.add(3);
		set.add(6);
		set.add(0);
		for (Integer i : set) {
			System.out.println(i);
		}
	}
}
out:
0
3
6

示例构造方法的引用,以下示例四种引用方式



import java.util.function.Supplier;

public class Student {
	public String name;

	public static Student creatStudent(Supplier<Student> s) {
		System.out.println("通过方法引用创建对象");
		return s.get();

	}

	public static void eat(Student student) {
		System.out.println("Student " + student.getName() + "is eating");
	}

	public void drink(Student s) {
		System.out.println("student" + s.getName() + "drink something");
	}

	public void study() {
		System.out.println("the student" + this.getName() + " has studyed 5 hours");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
		System.out.println("this student's name is " + name);
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return super.hashCode();
	}

	@Override
	public String toString() {
		System.out.println("Student [name=" + name + "]");
		return "Student [name=" + name + "]";
	}

}

//测试类


import java.util.Arrays;
import java.util.List;

public class Test06 {
	public static void main(String[] args) {
		// 构造方法引用
		Student s1 = Student.creatStudent(Student::new);
		Student s2 = Student.creatStudent(Student::new);
		s1.setName("张三");
		s2.setName("李四");
		Student[] ss = { s1, s2 };
		// 静态方法引用
		List<Student> listStu = Arrays.asList(ss);
		listStu.forEach(Student::eat);
		// 特定对象的方法引用
		listStu.forEach(s1::drink);
		// 特定类任意对象的特定方法
		listStu.forEach(Student::toString);
                listStu.forEach(Student::study);

	}
}
out:
通过方法引用创建对象
通过方法引用创建对象
this student's name is 张三
this student's name is 李四
Student 张三is eating
Student 李四is eating
student张三drink something
student李四drink something
Student [name=张三]
Student [name=李四]
the student张三 has studyed 5 hours
the student李四 has studyed 5 hours

猜你喜欢

转载自blog.csdn.net/sinat_41132860/article/details/84638568