一. 流
1.基本介绍
* Stream:是一个来自数据源的元素队列:
* 元素 是特定类型对象,形成一个队列,stream并不会存储元素,只是按需运算。
* 数据源 是流数据的来源,可以是集合或者队列。
* Stream操作有两个基础的特征:
* Pipelining:中间操作都会返回流对象本身,多个操作可以串联成一个管道。该操作可对延迟执行和短路进行操作
* 内部迭代:迭代器或增强for属于显式集合在外部迭代,Stream提供内部迭代,流可以直接调用遍历方法。
* 操作步骤: 获取数据源-->数据转换-->执行操作
* 获取流:
* 所有的Collection集合都可以通过stream默认方法获取流
* default Stream<E> stream()
* Stream接口的静态方法of可以获取数组对应的流
* static Stream<T> of (T...values)
* 参数是可变参数
public class Intro {
public static void main(String[] args) {
List<String> array = new ArrayList<>();
array.add("1111");
array.add("2222");
array.add("3333");
array.add("1444");
//转换为流对象,过滤,遍历
array.stream().filter(s -> s.length() == 4).filter(s -> s.startsWith("1")).forEach(s -> System.out.println(s));
//Set集合转换
Set<String> set=new HashSet<>();
set.stream();
//分别存储映射的键值
Map<String,String> map=new HashMap<>();
map.keySet().stream();
map.values().stream();
//键值映射关系
map.entrySet().stream();
//数组
Integer[] arr={1,2,3,4,5};
Stream<Integer> ss = Stream.of(arr);
int[] arr1={1,2,3,4};
Arrays.stream(arr1);
}
}
2.常用方法
* 流模型常用方法:
* 延迟方法:返回值仍然是Stream接口自身类型的方法,支持链式调用
* 终结方法:返回值不在是自身类型方法,中介方法包括count和forEach方法
* 方法:
* 如果需要将流中的元素映射到另一个流中,可以使用map方法:
* <R> Stream<R> map(Function< ? superT,? extends R> mapper>;
*
* count方法计算元素个数:
* long count()
*
* limit取用流中前几个元素;
* Stream<T> limit(long maxSize)
*
* skip跳过前几个元素:
* Stream<T> skip(long n)
*
* concat将两个流合并为一个流
* static <T> Stream<T> concat(Stream< ? extends T> a, Stream< ? extends T> b)
public class Method {
public static void main(String[] args) {
System.out.println("+++++++++++++++++++++++++Map类型映射+++++++++++++++++++++++++++++++++");
Stream<String> stream=Stream.of("111","211","311","4111");
stream.map((String s)->Integer.parseInt(s)).forEach(i-> System.out.println(i));
System.out.println("++++++++++++++++++++++++count计算元素+++++++++++++++++++++++++++++++++");
Stream<String> stream1=Stream.of("111","211","311","4111");
System.out.println("个数为:"+stream1.count());
System.out.println("++++++++++++++++++++++++++++limit取前几个+++++++++++++++++++++++++++++");
Stream<String> stream2=Stream.of("111","211","311","4111");
stream2.limit(2).forEach(s-> System.out.println(s));
System.out.println("++++++++++++++++++++++++++++++++skip跳过前几个+++++++++++++++++++++++++");
Stream<String> stream3=Stream.of("111","211","311","4111");
stream3.skip(2).forEach(s-> System.out.println(s));
System.out.println("++++++++++++++++++++++++++++++concat拼接++++++++++++++++++++++++++++++");
Stream<String> stream4=Stream.of("111","211","311","4111");
Stream<String> stream5=Stream.of("2111","2211","2311","24111");
Stream.concat(stream4,stream5).forEach(s -> System.out.println(s));
}
}
二. 方法引用
* 双冒号::为引用运算符,所在表达式被称为方法引用,
*
* 类型:
* 1,通过对象名引用成员方法:
* 2,通过类名引用静态方法:
* 3,通过super引用成员方法:
* 4,通过this引用成员方法:
* 5,类的构造器引用,改造方法引用
* 6,数据的构造器引用
1,通过对象名引用成员方法
* 通过对象名引用成员方法
* 对象名与成员方法都存在,通过对象名引用成员方法
@FunctionalInterface
public interface Printable {
void print(String s);
}
public class MethodRefer {
public void printUpperCaseString(String str){
System.out.println(str.toUpperCase());
}
}
public class Demo01 {
//定义一个方法,参数传递Printable接口
public static void pri(Printable p){
p.print("Hello");
}
public static void main(String[] args) {
//调用pri方法,参数是一个函数式接口,可传递lambda表达式
pri((s)->{
MethodRefer mr=new MethodRefer();
//调用对象中的成员方法
mr.printUpperCaseString(s);
});
//方法引用进行优化(对象存在,方法存在,对象::方法直接调用)
MethodRefer mr=new MethodRefer();
pri(mr::printUpperCaseString);
}
}
2,通过类名引用静态方法
* 通过类名引用静态成员方法
* 类与静态成员方法均存在
* 直接通过类名引用静态成员方法
@FunctionalInterface
public interface Calcable {
int CalAbs(int number);
}
public class Demo2 {
public static int method(int num,Calcable cc){
return cc.CalAbs(num);
}
public static void main(String[] args) {
int b=method(-5,(s)->{
return Math.abs(s);
});
System.out.println(b);
//使用方法引用优化表达式
//Math类与abs计算绝对值方法存在
int num=-5;
int b1=method(num,Math::abs);
System.out.println(b1);
}
}
3,通过super引用成员方法
* 通过super引用成员方法:
* 存在继承关系,需要出现super调用,可使用方法引用进行替代。
@FunctionalInterface
public interface Greatable {
void greet();
}
public class Father {
void sayHello(){
System.out.println("hello,this is father");
}
}
public class Son extends Father {
public void sayHello(){
System.out.println("hello, this is son");
}
public void method(Greatable g){
g.greet();
}
public void show(){
/*method(()->{
Father f=new Father();
f.sayHello();
});*/
method(()->{super.sayHello();});
method(super::sayHello);
}
public static void main(String[] args) {
new Son().show();
}
}
4,通过this引用成员方法
* this代表当前对象,引用方法为当前类中的成员方法,使用this::成员方法来使用方法引用
public interface Richable {
void buy();
}
public class Man {
public void buy1(){
System.out.println("方法1");
}
public void buy2(Richable r){
r.buy();
}
public void buy3(){
// buy2(()->{
// this.buy1();
// });
buy2(this::buy1);
}
public static void main(String[] args) {
new Man().buy3();
}
}
5,类的构造器引用,构造方法引用
* 构造器的名称与类名完全一样,并不固定,构造器可使用::new的格式表示
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public interface PersonBuilder {
Person bulidP(String name);
}
public class Intro {
public static void bulid(String name, PersonBuilder p) {
Person person = p.bulidP(name);
System.out.println(person.getName());
}
public static void main(String[] args) {
bulid("TOM", (String name) -> {
return new Person(name);
});
//使用方法引用优化表达式,构造方法new Person(String name)
//可以使用Person引用new创建对象
bulid("Tom", Person::new);
}
}
6,数据的构造器引用
* 数组也是Object的子类对象,同样具有构造器
* 数组的构造器引用
@FunctionalInterface
public interface ArrayBuilder {
int[] builderArray(int length);
}
public class Intro {
public static int[] creatArray(int length,ArrayBuilder ab){
return ab.builderArray(length);
}
public static void main(String[] args) {
int[] arr=creatArray(10,(len)->{
return new int[len];
});
System.out.println(arr.length);
int[] arr1=creatArray(10,int[]::new);
System.out.println(arr1.length);
}
}