方法引用
lambda的方法引用注意super ,this
super和this 的 引用 ,尤其是this不能调用本身的方法 ,内存溢出。
下面演示一段代码:
/**
* @auther SyntacticSugar
* @data 2018/9/2 0002下午 11:56
* 准备1 : Greetable 函数式接口中定义 greet 无参无返回值方法.
* 准备2 : 父类 Human 与子类 Man. 在子类中定义方法,把接口作为参数传进去
*
* 通过 super 来引用
*/
public class Test005 {
public static void main(String[] args) {
Man man = new Man();
man.sayHello();
}
}
//
interface Greetable {
void greet();
}
class Human {
public void say() {
System.out.println("我是熊大");
}
}
class Man extends Human {
public void sayHello(){
// lambda
method(()-> System.out.println("大家好"));
//
method(()->super.say());//通过super来调用 方法
//
method(super::say); //super 的引用写法
//
method(this::buy); //this的 引用写法 迪欧用本类中的方法
}
public static void method(Greetable greetable) {
greetable.greet();
}
public void buy(){
System.out.println("卖一辆宝马");
}
}
可以传进去lambda表达式,作为参数、
也可使用lambda的升级版,,方法引用。
针对this的运用,引用其成员方法(非自身)。
否则会造成死循环,内存溢出。
package Test02;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* @auther SyntacticSugar
* @data 2018/9/3 0003下午 9:41
*/
public class Test01 {
public static void main(String[] args) {
//1.请在测试类main方法中完成以下需求
//已知有Integer[] arr = {-12345, 9999, 520, 0,-38,-7758520,941213}
//a)使用lambda表达式创建 Predicate 对象p1,p1能判断整数是否是自然数(大于等于0)
//b)使用lambda表达式创建Predicate 对象p2,p2能判断整数的绝对值是否大于100
//c)使用lambda表达式创建Predicate对象p3,p3能判断整数是否是偶数
//
// 遍历arr,仅利用已创建的Predicate对象(不使用任何逻辑运算符),完成以下需求
//i.打印自然数的个数
//ii.打印负整数的个数
//iii.打印绝对值大于100的偶数的个数
//iv.打印是负整数或偶数的数的个数
Integer[] arr = {-12345, 9999, 520, 0, -38, -7758520, 941213};
// myMethod(arr, (num)->num>=0);
// sop("-------------------------------");
// myMethod(arr, (num)->Math.abs(num)>100);
// sop("-------------------------------");
// myMethod(arr, (num)->num%2==0);
// sop("-------------------------------");
Predicate p1 = (s) -> s >= 0;
Predicate p2 = (s) -> Math.abs(s) > 100;
Predicate p3 = (s) -> s % 2 == 0;
//
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;//负数的个数
for (Integer integer : arr) {
if (p1.test(integer)) {
count1++;
}else {
count4++;
}
if (p2.test(integer)) {
count2++;
}
if (p3.test(integer)||!p1.test(integer)) {
count3++;
}
}
sop(count1);//4
sop(count4);//3
sop(count2);//5
sop(count3);//5
}
// public static void myMethod(Integer[] arr, Predicate one) {
// for (Integer integer : arr) {
// boolean result = one.test(integer);
// System.out.println(integer+"判断的结果为:"+result);
// }
// }
public static void sop(Object obj) {
System.out.println(obj);
}
}
练习2
package Test02;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* @auther SyntacticSugar
* @data 2018/9/3 0003下午 10:10
*
* default Function
*/
public class Test02 {
public static void main(String[] args) {
//1.使用lambda表达式分别将以下功能封装到Function对象中
//a)求Integer类型ArrayList中所有元素的平均数
//b)将Map中value存到ArrayList中
//2.已知学生成绩如下
//姓名 成绩
//岑小村 59
//谷天洛 82
//渣渣辉 98
//蓝小月 65
//皮几万 70
//3.以学生姓名为key成绩为value创建集合并存储数据,使用刚刚创建的Function对象求学生的平均成绩
// Function, Integer> arrayListIntegerFunction = new Function<>();
Function, Integer> p1 = (s) -> {
int sum = 0;
for (int i = 0; i < s.size(); i++) {
sum += s.get(i);
}
return sum / s.size();
};
//
Function
package Test02;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import static Test02.Test01.sop;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 8:59
*/
public class Test03 {
public static void main(String[] args) {
//简述单列集合、双列集合、数组分别如何获取Stream流对象,并进行演示
//数组的并发流 获取
ArrayList list = new ArrayList<>();
Stream stream = list.stream();
HashMap map = new HashMap<>();
Stream stream1 = map.values().stream();//value
Stream stream2 = map.keySet().stream();//key
Stream> stream3 = map.entrySet().stream();//entry 健值对
//以下为静态 stream.of 的底层实现
/**public interface Stream extends BaseStream>
* //public interface BaseStream>
* extends AutoCloseable -->@return the element spliterator for this stream
* 返回并发流
*/
Integer[] integers = {2, 3, 4, 5, 6, 7, 8, 9, 10};
Stream integers1 = Stream.of(integers);//
integers1.forEach(System.out::print);
/**以下为Arrays.stream
* * @return a {@code Stream} for the array range
* 返回数组范围的 stream //return stream(array, 0, array.length);
*/
Stream stream4 = Arrays.stream(integers);
sop(integers1);//java.util.stream.ReferencePipeline$Head@3834d63f
sop(stream4);//java.util.stream.ReferencePipeline$Head@1ae369b7
}
}
练习4
package Test02;
import java.util.Arrays;
import java.util.stream.Stream;
import static Test02.Test01.sop;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 9:24
*/
public class Test04 {
public static void main(String[] args) {
//有如下7个元素 "黄药师", "冯蘅", "郭靖", "黄蓉", "郭芙", "郭襄", "郭破虏"
// 将以郭字开头的元素存入新数组
/**analyze:
*stream . of 获取stream
*使用filter 过滤出 不是姓郭的name
*
* 储存在数组中 , toArray()--->返回object 数组
* toArray(A[]..)----->返回A类型的数组
*/
Stream stringStream = Stream.of("黄药师", "冯蘅", "郭靖", "黄蓉", "郭芙", "郭襄", "郭破虏");
Stream stream = stringStream.filter((name) -> !name.startsWith("郭"));
String[] strings = stream.toArray(String[]::new);
//遍历
sop(Arrays.toString(strings));//[黄药师, 冯蘅, 黄蓉]
}
}
package Test02;
import java.util.ArrayList;
import java.util.Arrays;
import static Test02.Test01.sop;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 9:36
*/
public class Test05 {
public static void main(String[] args) {
//已知ArrayList集合中有如下元素{陈玄风、梅超风、陆乘风、曲灵风、武眠风、冯默风、罗玉风},使用Stream
//1、取出前2个元素并在控制台打印输出。
//2、取出后2个元素并在控制台打印输出。
/**analyze:
*
* 获取ArrayList 的stream
*limit 使用 限制size=2
* skip
*/
String[] str = {"陈玄风","梅超风","陆乘风","曲灵风","武眠风","冯默风","罗玉风"};
ArrayList list = new ArrayList<>();
for (String s : str) {
list.add(s);
}
//
list.stream().limit(2).forEach(System.out::println);
sop("------------------------------------");
//
list.stream().skip(list.size()-2).forEach(System.out::println);
}
}
练习:
package Test02;
import java.util.Arrays;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 9:52
*
* Stream map(Function mapper)
* 返回由给定函数应用于此流的元素的结果组成的流。
*/
public class Test06 {
public static void main(String[] args) {
/**多个条的判断使用函数拼接
*
*
* map skip concat limit filter
*/
//有如下整数 1,-2,-3,4,-5
//使用Stream取元素绝对值并打印
Integer[]integers={1,-2,-3,4,-5};
Arrays.stream(integers).map((s)->Math.abs(s)).forEach(System.out::println);
}
}
package Test02;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 10:33
*/
public class Test07 {
public static void main(String[] args) {
//已知数组arr1中有如下元素{"郭靖","杨康"};,arr2中有如下元素{"黄蓉","穆念慈"},
// 使用Stream将二者合并到List集合
/**
*analyze:
* 分别获取 str1 str2 数组,然后concat拼接(Stream 静态调用)
*把拼接后的stream 放进(收集)list中
*/
String[] arr1 = {"郭靖", "杨康"};
String[] arr2 = {"黄蓉", "穆念慈"};
Stream stream1 = Arrays.stream(arr1);
Stream stream2 = Arrays.stream(arr2);
//
ArrayList list = new ArrayList<>();
List list1 = Stream.concat(stream1, stream2).collect(Collectors.toList());//转化为list
list1.forEach(System.out::println);//调用stream
}
}
package Test02;
import java.util.ArrayList;
import java.util.stream.Stream;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 10:45
*
*并发流 两种方式;① 直接获取流 ,②调用pa
*/
public class Test08 {
public static void main(String[] args) {
//请分别写出获取并发流的两种方式。
/**@return a possibly parallel {@code Stream} over the elements in this
* collection
* //parallelStream 是collection定义的
*
* //parallel 是baseStream 定义的
*
*/
ArrayList list = new ArrayList<>();
Stream ps1 = list.parallelStream();//直接获取
Stream parallel = list.stream().parallel();//使用parallel 调用
}
}
package Test02;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static Test02.Test01.sop;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 10:58
*
* 多个条件 使用函数拼接
*/
public class Test09 {
public static void main(String[] args) {
//现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用Stream方式进行以
//下若干操作步骤:
//1. 第一个队伍只要名字为3个字的成员姓名;
//2. 第一个队伍筛选之后只要前6个人;
//3. 第二个队伍只要姓张的成员姓名;
//4. 第二个队伍筛选之后不要前1个人;
//5. 将两个队伍合并为一个队伍;
//6. 根据姓名创建Student对象;
//7. 打印整个队伍的Student对象信息。
List one = new ArrayList<>();
String[] str1 = {"陈玄风", "梅超风", "陆乘风", "曲灵风", "武眠风", "冯默风", "罗玉风"};
for (String s : str1) {
one.add(s);
}
// 2条件
Stream stream1 = one.stream().filter((name) -> name.length() == 3).limit(6);
// stream1.forEach(System.out::println);
sop("----------------------------------------------");
List two = new ArrayList<>();
String[] str2 = {"宋远桥", "俞莲舟", "俞岱岩", "张松溪", "张翠山", "殷梨亭", "莫声谷"};
for (String s : str2) {
two.add(s);
}
// 2 条件
Stream stream2 = two.stream().filter(name -> name.startsWith("张")).skip(1);
// stream2.forEach(System.out::println);
// //队伍合并 ---->list集合中
// List list = Stream.concat(stream1, stream2).collect(Collectors.toList());
// list.stream().map(Student::new).forEach(System.out::println);
5. 将两个队伍合并为一个队伍;//6. 根据姓名创建Student对象;//7. 打印整个队伍的Student对象信息。
Stream.concat(stream1, stream2).map(Student::new).forEach(System.out::println);
}
}
class Student{
private String name;
//
public Student(String name) {
this.name = name;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
package Test02;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static Test02.Test01.sop;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 11:25
*/
public class Test10 {
public static void main(String[] args) {
//以下是某不知名机构评出的全球最佳影片及华人最佳影片前十名 :
//全球
// 1、 《教父》
// 2、 《肖申克的救赎》
// 3、 《辛德勒的名单》
// 4、 《公民凯恩》
// 5、 《卡萨布兰卡》
// 6、 《教父续集》
// 7、 《七武士》
// 8、 《星球大战》
// 9、 《美国美人》
// 10、 《飞跃疯人院》
//
//华人
// 1、 《霸王别姬》
// 2、 《大闹天宫》
// 3、 《鬼子来了》
// 4、 《大话西游》
// 5、 《活着》
// 6、 《饮食男女》
// 7、 《无间道》
// 8、 《天书奇谭》
// 9、 《哪吒脑海》
// 10、 《春光乍泄》
//
//
//1、现将两个榜单中的影片名,分别按排名顺序依次存入两个ArrayList集合
//2、通过流的方式
// 1)打印全球影片排行榜中的前三甲影片名
// 2)打印华人影片排行榜中倒数5名的影片名
// 3)将两个排行榜中的前5名挑出来共同存入新的集合
// 4)定义电影 Film 类,以影片名为name创建Film对象并保存至集合
String[] strings1 = {"《教父》","《肖申克的救赎》","《辛德勒的名单》","《公民凯恩》","《卡萨布兰卡》",
"《教父续集》","《七武士》","《星球大战》","《美国美人》","《飞跃疯人院》"};
ArrayList list1 = new ArrayList<>();
for (String s : strings1) {
list1.add(s);
}
//条件
list1.stream().limit(3).forEach(System.out::println);
Stream limit1 = list1.stream().limit(5);//前五
sop("-----------------------------------");
String[] strings2 = {"《霸王别姬》","《大闹天宫》","《鬼子来了》","《大话西游》"," 《活着》",
"《饮食男女》","《无间道》","《天书奇谭》","《哪吒脑海》","《春光乍泄》" };
ArrayList list2 = new ArrayList<>();
for (String s : strings2) {
list2.add(s);
}
//条件
list2.stream().limit(list2.size()-5).forEach(System.out::println);
Stream limit2 = list2.stream().limit(5);//前五
// 4)定义电影Film类,以影片名为name创建Film对象并保存至集合
List newList = Stream.concat(limit1, limit2).collect(Collectors.toList());
//
newList.stream().map(Film::new).forEach(System.out::println);//创建打印
}
}
class Film{
private String name;
public Film(String name) {
this.name = name;
}
public Film() {
}
//
@Override
public String toString() {
return "Film{" +
"name='" + name + '\'' +
'}';
}
}
综合练习:
package Test02;
import java.util.Arrays;
import static Test02.Test01.sop;
/**
* @auther SyntacticSugar
* @data 2018/9/4 0004上午 11:47
*/
public class Test11 {
public static void main(String[] args) {
//我国有34个省级行政区,分别是:
//23个省:
//河北省、山西省、吉林省、辽宁省、黑龙江省、陕西省、甘肃省、青海省、山东省、福建省、
//浙江省、台湾省、河南省、湖北省、湖南省、江西省、江苏省、安徽省、广东省、海南省、四川省、贵州省、云南省。
//4个直辖市:
//北京市、天津市、上海市、重庆市。
//5个自治区:
//内蒙古自治区、新疆维吾尔自治区、宁夏回族自治区、广西壮族自治区、西藏自治区。
//2个特别行政区:
//香港特别行政区、澳门特别行政区。
//
//使用流:
//1、统计三个字的省份的个数
//2、统计名字中包含方位名词的省份(东西南北)的个数
//3、打印名字中包含方位名词的普通省份(非自治区直辖市特别行政区)的名字
//4、将所有的特殊省份(自治区直辖市特别行政区)提取出来并放到新数组中
String[]strings1={"河北省","山西省","吉林省","辽宁省","黑龙江省","陕西省","甘肃省","青海省","山东省",
"福建省", "浙江省","台湾省","河南省","湖北省","湖南省","江西省","江苏省","安徽省","广东省",
"海南省","四川省", "贵州省","云南省","北京市","天津市","上海市","重庆市",
"内蒙古自治区","新疆维吾尔自治区","宁夏回族自治区","广西壮族自治区","西藏自治区",
"香港特别行政区","澳门特别行政区"};
long count = Arrays.stream(strings1).filter((s) -> s.length() == 3).count();
sop(count);//打印count 26
//
long count1 = Arrays.stream(strings1).filter((s) -> s.contains("东") || s.contains("南")
|| s.contains("西") || s.contains("北")).count();
sop(count1);//14
//
long count2 = Arrays.stream(strings1).filter((s) -> s.contains("东") || s.contains("南")
|| s.contains("西") || s.contains("北")).filter((s) -> s.contains("省")).count();
sop(count2);
//将所有的特殊省份(自治区直辖市特别行政区)提取出来并放到新数组中
String[] strings = Arrays.stream(strings1).filter((s) -> !s.contains("省")).toArray(String[]::new);
for (String string : strings) {
sop(string);
}
}
}