目录
1.Map 中Properties
2.Collections工具类
3.lanbda表达式
4.四大内置函数式接口
5.方法 构造器 数组的引用
6.Stream流
1.Propertise
用途 :此类用来表示一组持久的属性,可以保存到流中或者在流中加载;一般作为配置文件存在。
语法:属性列表中每个键值对的其对应值都为String字符串。
作为配置文件
1.src下定义一个文件xx.properties
2.在文件中定义键值对的数据
3.构建Properties类型的对象pro
4.pro.load(流) 从流中加载键值对属性数据
public static void main(String[] args) throws IOException {
Properties a = new Properties();
a.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("test01.properties"));
a.getProperty("url");
a.getProperty("username");
a.getProperty("password");
System.out.println(a.getProperty("url"));
System.out.println(a.getProperty("username"));
System.out.println(a.getProperty("password"));
StringBuilder s = new StringBuilder();
}
Collections工具类
/**
* void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。
* void shuffle(List) //对List容器内的元素进行随机排列
* void reverse(List) //对List容器内的元素进行逆续排列
* void fill(List, Object) //用一个特定的对象重写整个List容器
* int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象
*/
public static void main(String[] args){
/**
* bug
* 1.导包
* 2.Arrays.asList返回可变的list,而List.of返回的是不可变的list
* 3.Arrays.asList支持null,而List.of不行,Arrays.asList:数组的修改会影响原数组。
*/
List<Integer> arr = Arrays.asList(1,3,5,7,9,0,4,8,1,915,6);
//升序排序
Collections.sort(arr);
System.out.println(arr);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~``");
//折半查找 默认升序 返回值为int
Collections.binarySearch(arr,9);
System.out.println(Collections.binarySearch(arr,9));
//List元素随机排列
Collections.shuffle(arr);
System.out.println(arr);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~``");
//List元素的逆序排序
Collections.sort(arr);
System.out.println(arr);
Collections.reverse(arr);
System.out.println(arr);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~``");
//用一个特定的元素覆盖List
Collections.fill(arr,66);
System.out.println(arr);
}
Lambda表达式
作用:为了简化匿名内部类对象
使用前提:函数式接口–>函数式接口:接口中只有一个必须被重写的抽象方法–>函数式接口的检查**@FunctionalInterface**
语法格式:()->{} ()中写抽象方法的参数列表 ->箭头函数lambda符号,具有上下文推到的作用 {}内写需要重写的方法体
lambda简化 ===> 5
package yjjxt.java51.week4;
public class Demo02 {
public static void main(String[] args) {
//lambda表达式的简化 定义接口
//完整的表达
Smoke smoke = new Smoke() {
@Override
public void smoking() {
}
};
smoke = ()->{
System.out.println("<( ̄ c ̄)y▂ξ抽烟有害身体");
};
smoke.smoking();
//当重写方法体只有一句话 可以省略{}
System.out.println("分隔符!~~~~~~~~~~~~~~~~~~~~~~~~");
smoke =()-> System.out.println("简化第一步");
smoke.smoking();
//参数数据类型可以省略
System.out.println("分隔符!~~~~~~~~~~~~~~~~~~~~~~~~");
Smoke1 smoke1 = (int x)-> System.out.println(x);
smoke1.smoking1(6);
//参数只有一个()可以省略
System.out.println("分隔符!~~~~~~~~~~~~~~~~~~~~~~~~");
Smoke1 smoke2 = x-> System.out.println(x);
smoke2.smoking1(6);
//重写的抽象方法如果有返回值 且方法体中只有一条语句为return {}return都可以省略
}
}
@FunctionalInterface
interface Smoke{
void smoking();
}
interface Smoke1{
void smoking1(int i);
}
//行为当做参数传递
//TreeSet(Comparator<? super E> comparator)
Comparator<Person> com = new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.age-o2.age;
}
};
//lambda : 行为当做参数传递,配合函数式接口作为形参,。可以写出更简洁、更灵活的代码。
测试题::
/*
* 题一:调用Collections.sort()方法,通过定值排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递
* 分析:
* 1.定制排序:指自定义比较器|定制排序
* 自然排序:内部比较器|自然排序
* 2.先比较年龄,年龄相同才比较姓名
*/
public class Class001_TestLambda {
public static void main(String[] args) {
List<Employee> emps = new ArrayList<>();
emps.add(new Employee(1001,"彭鑫",17,30000));
emps.add(new Employee(1002,"刘新宇",16,18000));
emps.add(new Employee(1003,"黄伟",16,17000));
// public static <T> void sort(List<T> list, Comparator<? super T> c)
Collections.sort(emps,(x,y)->{
if( x.getAge()==y.getAge()){
return x.getName().compareTo(y.getName());
}
return x.getAge()-y.getAge();
});
System.out.println(emps);
System.out.println((int)'刘');
System.out.println((int)'黄');
}
}
/*
* 习题二:
* 1)声明函数式接口,接口中声明抽象方法,public String getValue(String str)
* 2)声明类 TestLambda,类中编写方法使用接口作为参数,讲一个字符串转成大写,并作为方法的返回值
* 3)再将一个字符串的第2个和第4个索引位置进行截取子串
*/
public class Class002_TestLambda {
public static void main(String[] args) {
System.out.println(strHandler("hahahehexixi",s->s.toUpperCase()));;
System.out.println(strHandler("hahahehexixi",s->s.substring(2,5)));;
System.out.println(strHandler(" hahahehexixi ",s->s.trim()));;
}
//对某一个字符串进行某种行为的操作,返回结果
public static String strHandler(String str,MyFunction my){
return my.getValue(str);
}
}
@FunctionalInterface
interface MyFunction{
public String getValue(String str);
}
/*
* 习题三:
* 1)声明一个带两个泛型的函数式接口,泛型类型为<T,R> T为参数,R为返回值
* 2)接口中声明对应抽象方法
* 3)在TestLambda类中声明方法,参数三个,两个long类型的参数,接口作为参数,接口实现中计算两个long型参数的和
* 4)再计算两个long型参数的乘积
*/
public class Class003_TestLambda {
public static void main(String[] args) {
System.out.println(testLong(100L,200L,(x,y)->x+y));;
System.out.println(testLong(100L,200L,(x,y)->x*y));;
System.out.println(testLong(100L,200L,(x,y)->x/y));;
}
public static Long testLong(Long l1,Long l2,MyFunction2<Long,Long> my){
return my.test(l1,l2);
}
}
interface MyFunction2<T,R>{
R test(T t1,T t2);
}
四大内置函数式接口
消费型接口 Consumer void accept(T t) 有一个参数没有返回值
函数型接口 Function<T,R> R apply(T t) 有一个参数有一个返回值
断言型接口 Predicate boolean test(T t)一个参数一个boolean 的返回值
供给型接口Supplier T get() 没有参数 一个返回值
public static void main(String[] args) {
testConsumer(20000,d-> System.out.println("今天给主播托马斯刷4个藏宝图消费"+d));
testConsumer(10000,d-> System.out.println("今天出去喝酒消费"+d));
System.out.println(strHandler(" haha",s->s.trim()));
System.out.println(strHandler(" haha",s->s.toUpperCase()));
//[5,10]
System.out.println(testSupplier(5,()->(int)(Math.random()*(10-5+1)+5)));;
System.out.println(testPredicate(List.of("abcd","abc","ab","a"),s -> s.length()<=3));
}
//对集合中的字符串数据做某种要求的过滤
public static List<String> testPredicate(List<String> list, Predicate<String> pre){
List<String> ls = new ArrayList<>();
for(String s:list){
if(pre.test(s)){
ls.add(s);
}
}
return ls;
}
//生成n个随机数
public static List<Integer> testSupplier(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for(int i=1;i<=num;i++){
list.add(sup.get());
}
return list;
}
//对于某个字符串进行某种行为的操作,得到结果
public static String strHandler(String str, Function<String,String> fun){
return fun.apply(str);
}
//消费
public static void testConsumer(double money, Consumer<Double> com){
com.accept(money);
}
引用
方法引用
方法引用 : 当lambda体{}的实现,已经有另外的方法实现了,可以通过方法引用来引用那个方法(引用|调用)
方法引用可以理解为: lambda表达式的另外一种表现形式
方法引用是用来简化lambda表达式
要求:1)lambda体的实现,是通过调用|引用另外一个方法实现的
2)引用的方法的参数列表与返回值要求与要重写的抽象方法的参数列表与返回值保持一致,自动匹配
3)如果返回值匹配,但是参数列表不完全匹配,可以考虑是否满足第三种情况: 使用 类名::成员方法名 简化
如果参数列表只有一个,这个参数作为内部调用方法的对象存在
如果参数列表存在多个,第一个参数作为内部调用方法的对象,第二个参数开始自动匹配内部所引用方法的参数列表
使用方式:
对象::成员方法名 : 对象真实存在
类名::静态方法名
类名::成员方法名 : 对象自动匹配,对象是lambda的参数提供的
//类名::成员方法名
public static void test3(){
BiPredicate<String,String> biPredicate = (x,y)->x.equals(y);
//分析: 1)lambda体是否是通过调用了另外一个 方法实现的 equals 2)如果参数列表存在多个,第一个参数作为内部调用方法的对象,第二个参数开始自动匹配内部所引用方法的参数列表
biPredicate = String::equals;
System.out.println(biPredicate.test("zhangsan","zhangsan2"));;
}
//类名::静态方法名
public static void test2(){
BiFunction<Integer,Integer,Integer> biFunction = (x,y)-> Math.max(x,y);
//分析: 1)lambda体的实现是通过调用了另一个方法实现的,Math.max() 2)lambda的参数列表与返回值刚好匹配到内部所调用的max()方法的参数列表与返回值
biFunction =Math::max;
System.out.println(biFunction.apply(101,102));
}
//对象::成员方法名
public static void test1(){
Consumer com = o ->{
System.out.println(o);
};
PrintStream ps = System.out;
com = o ->{
ps.println(o);
};
//分析:
//1)lambda体的实现是通过调用了println方法实现的
//2)抽象方法accept参数列表与返回值类型匹配到println方法参数列表与返回值
//--> 方法引用简化
com = ps::println;
com.accept("你好");
List<Integer> ls = List.of(1,2,3,4,5);
ls.forEach(System.out::println);
构造器引用 数组的引用
构造器引用 数据类型::new
要求: lambda参数列表与构造器的参数列表保持一致
数组的引用 数据类型 :new
//构造器引用
Function<String,String> fun = (s)->new String(s);
fun = String::new;
System.out.println(fun.apply("abc"));;
Supplier<Employee> sup = () -> new Employee();
sup = Employee::new;
System.out.println(sup.get());
//数组 引用
Function<Integer,int[]> sup2 = (i)->new int[i];
sup2 = int[]::new;
System.out.println(sup2.apply(3));
System.out.println(Arrays.toString(sup2.apply(3)));
Stream流
定义:数据的渠道,用来操作由数据源(数组,集合)产生元素序列
区别:数组|集合关注数据的存储,Stream关注的是对数据的计算可以根据数据源锁产生的数据进行一些列的流式计算
特点:
1.Stream本身不能存储数据
2.Stream不会修改原对象|数据源中的数据,在每次进行流式操作后会返回一个持有结果的新的流
3.惰性加载|延迟执行: 在进行stream操作时候不会马上执行,会在获取结果时一起执行
4.流式一次性的流,流是不能重复使用,因为这个流已经被使用消费了
使用Stream的过程:
1.获取流
2.一系列流式的中间操作 (返回持有结果的新的流)
3.终止行为(返回真实结果)
创建流:
1. Collection中的成员stream()
2. Arrays.stream(数组)
3.Stream.of(数据)
2. 中间操作 : 筛选与切片
filter: 过滤
limit:限制从流中获得前n个数据
distinct:去重
skip:跳过前n个数据
3. 终止操作
List<Employee> list = List.of(
new Employee(1001,"zhangsan",18,20000),
new Employee(1002,"lisi",25,18000),
new Employee(1003,"wangwu",30,15000),
new Employee(1004,"zhaoliu",28,10000),
new Employee(1004,"zhaoliu2",28,10000),
new Employee(1004,"zhaoliu",28,10000)
);
//1.获取流
Stream<Employee> stream = list.stream();
//2.中间操作
stream = stream.filter(employee ->employee.getAge()>18)
.distinct()/*要求重写hashCode与equals*/
.limit(3)
.skip(1);
//3.终止行为
stream.forEach(System.out::println);