• 笔记-迎难而上之Java基础进阶-终


    使用Stream流的方式,遍历集合

    import java.util.*;
    public class StreamDemo{
    	public static void main(String[] args){
    		List<String> list = new ArrayList<>();
    		list.add("张无忌");
    		list.add("周芷若");
    		list.add("赵敏");
    		list.add("张强");
    		list.add("张三丰");
    		//创建Stream流
    		list.stream()
    				//只要姓张的
    				.filter(name->name.startsWith("张"))
    				//只要长度等于三的
    				.filter(name->name.length()==3)
    				.forEach(name->System.out.println(name));
    	}
    }
    
    两种获取流的方式

    java.util.stream.Stream是Java 8 新加入的最常用的流接口

    获取一个非常简单,有一下几种常用的方式:

    所有的Collection集合都可以通过stream默认方法获取流(Collection单列集合),该类有一个默认方法"stream",他会返回一个流,所有的Collection集合的子类都可以通过该方法获取stream流

    ​ Stream接口的静态方法 of 可以获取数组对应的流

    ​ static Stream of(T... values) 参数是一个可变参数,可变参数的底层是数组,返回值是一个Stream流

    public class StreamDemo1{
        public static void main(String[] args){
            //把集合转换为Stream流
            List<String> list = new ArrayList<>();
            //调用方法stream,可以把集合转换成流对象
            Stream<String> stream1=list.stream();
    	   //Set集合也是一个单列集合,继承自Collection接口,所以可以通过stream获取流对象
            Set<String> set = new HashSet<>();
            Stream<String> stream2 = set.stream();
            //Map集合是双列集合,不是Collection接口的子类,获取Stream需要间接获取
            Map<String,String> map = new HashMap<>();
            //通过keySet()方法先把键key获取出来,存储到Set集合中去,就可以获取key的Stream流了
            Set<String> keySet = map.keySet();
            Stream<String> stream3 = keySet.stream();
            //获取值得流,可以通过方法HashMap的方法values();该方法返回的类型是一个Collection集合
            Collection<String> values = map.values();
            Stream<String> stream4 = values.stream();
            //获取键值对
            Set<Map.Entry<String,String>> entries = map.entrySet();
            Stream<Map.Entry<String,String>> stream5 = entries.stream();
            
            //通过Stream类中的静态方法 of 把数组转换成流对象
            Stream<Integer> stream6 = Stream.of(1,2,3,4,5);
            Integer[] arr  = {1,2,3,4,5};
            Stream<Integer> stream7 = Stream.of(arr);
        }
    }
    
    Stream流中的常用方法_forEach

    延迟方法:返回值类型仍然是Stream接口自身类型的方法

    终结方法:返回值类型不再是Stream接口自身类型的方法

    import java.util.stream.*;
    public class ForEachDemo{
    	public static void main(String[] args){
    		//创建一个Stream流
    		Stream<String> stream = Stream.of("云想衣裳花想容","春风扶槛露华浓","若非群玉山头见","会向瑶台月下逢");
    		//使用Stream流中的方法foEach对Stream流中的数据进行遍历
    		//该方法接收一个Consumer接口函数,会将每一个流元素交个该函数进行处理
    		stream.forEach((String name)->{System.out.println(name);});
    	}
    }
    

    filter方法

    filter方法的参数是Predicate接口,该接口有的方法

    import java.util.stream.*;
    public class FilterDemo{
    	public static void main(String[] args){
    		Stream<String> stream1 = Stream.of("张三丰","张翠山","赵敏","周芷若","张无忌");
    		//filter方法的参数Predicate是一个函数式接口,所以可以传递Lambda
    		//Predicate接口的test方法返回值类型是boolean
    		Stream<String> stream2 = stream1.filter((String name)->{ return name.startsWith("张");});
    		//遍历集合
    		stream2.forEach((String name)->{System.out.println(name);});
    	}	
    }
    

    Stream流属于管道流,只能被消费一次,第一个Stream流调用完毕方法,数据就会流转到下一个Stream上,而这时第一个Stream流已经使用完毕,就会关闭,所以第一个Stream就不能再调用方法了

    map方法

    如果需要将流中的元素映射到另一个流中,可以使用map方法,该方法的参数需要一个Function函数式接口参数,可以将当流中的T类型转换为另一个R类型的流

    Function中的抽象方法: R apply(T t);

    import java.util.stream.*;
    public class StreamMap{
    	public static void main(String[] args){
    		Stream<String> stream1 = Stream.of("1","2","3","4","5");
    		//把字符串类型的Stream转换成Integer类型的Stream
    		//可以使用map方法
    		Stream<Integer> stream2 = stream1.map((String s)->{
    			//使用Integer类的方法parseInt把每一个元素变成Integer类型
    			return Integer.parseInt(s);
    		});
    		stream2.forEach((integer)->{System.out.println(integer);});
    	}
    }
    

    count方法

    import java.util.stream.*;
    import java.util.*;
    //用来统计Stream流中的元素个数
    //count方法是一个终结方法,使用该方法后,该流不能再调用其他方法
    public class CountDemo{
    	public static void main(String[] args){
    		ArrayList<Integer> list = new ArrayList<>();
    		for(int i=0;i<=5;i++){
    			list.add(i);
    		}
    		//获取Stream
    		Stream<Integer> stream = list.stream();
    		//统计list集合的元素有几个
    		long count = stream.count();
    		System.out.println(count);
    	}
    }
    

    limit截取方法

    import java.util.stream.*;
     class StreamLimit{
    	public static void main(String[] args){
    		String[] arr={"美羊羊","喜羊羊","懒羊羊","灰太狼","红太狼"};
    		Stream<String> stream = Stream.of(arr);
    		//使用limit对Stream流中元素截取
    		Stream<String> stream2 = stream.limit(3);
    		stream2.forEach((n)->{System.out.println(n);});
    	}
         /*
         美羊羊
    	喜羊羊
    	懒羊羊
         */
    }
    

    skip跳过指定元素方法

    import java.util.stream.*;
     class StreamLimit{
    	public static void main(String[] args){
    		String[] arr={"美羊羊","喜羊羊","懒羊羊","灰太狼","红太狼"};
    		Stream<String> stream = Stream.of(arr);
    		//使用skipt对Stream流中元素进行跳过
    		Stream<String> stream2 = stream.skip(3);
    		stream2.forEach((n)->{System.out.println(n);});
    	}
    }
    

    concat方法,可以把流组合在一起

    import java.util.stream.*;
    import java.util.*;
    public class StreamConcat{
    	public static void main(String[] args){
    		Stream<String> stream1 = Stream.of("魔术师","科比","詹姆斯","邓肯","奥尼尔");
    		Stream<String> stream2 = Stream.of("基德","乔丹","皮蓬","诺维斯基","穆大叔");
    		//把两个流组合在一起
    		Stream<String> concat = Stream.concat(stream1,stream2);
    		concat.forEach((name)->{
    		System.out.println(new Random().nextInt(100)+"号"+name);
    		});
    	}
    }
    

    练习

    img

    import java.util.stream.*;
    import java.util.*;
    public class StreamTest{
        public static void main(String[] args){
            //第一只队伍
            ArrayList<String> one = new ArrayList<>();
            one.add("迪丽热巴");
            one.add("宋远桥");
            one.add("苏星河");
            one.add("石破天");
            one.add("石中玉");
            one.add("老子");
            one.add("庄子");
            one.add("洪七公");
            //调用方法stream转换成Stream流
            Stream<String> oneStream = one.stream();
            //过滤			把名字长度为3的返回给新的流
            Stream<String> newStream = oneStream.filter((String name)->{return name.length()==3;});
            //过滤,只要前面三个
            Stream<String> new2Stream = newStream.limit(3);
            //第二只队伍
            ArrayList<String> two = new ArrayList<>();
            two.add("古力娜扎");
            two.add("张无忌");
            two.add("赵丽颖");
            two.add("张三丰");
            two.add("尼古拉斯赵四");
            two.add("张天爱");
            two.add("张二狗");
            //创建流
            Stream<String> twoStream = two.stream();
            //只要姓张的
            Stream<String> s1 =twoStream.filter((String name)->{return name.startsWith("张");});
            //不要前面两个,使用跳过方法
            Stream<String> s2 = s1.skip(2);
            //组合两个流,合并在一起
            Stream<String> s3 = Stream.concat(new2Stream,s2);
            s3.map(name->new Person(name)).forEach(p->System.out.println(p));
        }
    }
    
    

    方法引用

    通过对象名来引用成员方法

    通过对象名引用成员方法

    使用前提是对象名是已经存在的,成员方法也是已经存在,就可以使用对象名来引用成员方法

    public interface Printable{
    	public abstract void print(String s);
    }
    
    public class MethodRerObject{
    	public void printUpperCaseString(String str){
    		System.out.println(str.toUpperCase());
    	}
    }
    
    public class ObjectMethodReference{
    	//定义一个方法,方法的参数传递Printable接口
    	public static void printString(Printable p){
    		p.print("Hello");
    	}
    	
    	public static void main(String[] args){
    		printString((s)->{
    			//创建MethodRerObject对象
    			MethodRerObject obj = new MethodRerObject();
    			//
    			obj.printUpperCaseString(s);
    		});
    		//使用方法引用优化Lambda
    		//对象是已经存在的,成员方法也是已经存在的MethodRerObject
    		//所以我们可以使用对象名引用成员方法printUpperCaseString
    		MethodRerObject obj = new MethodRerObject();
    		printString(obj::printUpperCaseString);
    	}
    }
    

    通过类名引用静态成员方法

    public interface Calcable{
        //该接口用于实现获取一个绝对值
        //接口要实现的功能在Lambda表达式里实现了
    	public abstract int calsAbs(int number);
    }
    
    public class StaticMethodReference{
    	public static int method(int number,Calcable c){
    		return c.calsAbs(number);
    	}
    	
    	public static void main(String[] args){
            //使用Lambda表达式来实现一个绝对值
    		int number = method(-10,(n)->{
                //使用类Math的方法获取绝对值,实现接口功能
    			return Math.abs(n);
    		});
    		System.out.println(number);
    		
    		//使用方法引用优化Lambda表达式
    		//Math类是存在的
    		//abs计算绝对值的静态方法也是存在的,所以可以通过类名引用静态方法
    		int number2 = method(-10,Math::abs);
    		System.out.println(number2);
    	}
    }
    
    super引用父类的成员方法
    public class Human{
    	public void sayHello(){
    		System.out.println("Hello 我是Human");
    	}
    }
    
    public interface Greetable{
    	public abstract void greet();
    }
    
    public class Man extends Human{
    	public void sayHello(){
    		System.out.println("Hello 我是Man");
    	}
    	
    	public void method(Greetable g){
    		g.greet();
    	}
    	
    	public void show(){
    		method(()->{
    			Human h = new Human();
    			h.sayHello();
    		});
    		method(()->{
    			super.sayHello();
    		});
    		method(super::sayHello);
    	}
    	public static void main(String[] args){
    		new Man().show();
    	}
    }
    

    this引用本类的成员方法

    public interface Richable{
    	public abstract void buy();
    }
    
    public class Husband{
    	public void buyHouse(){
    		System.out.println("北京二环内买一套四合院");
    	}
    	
    	public void marry(Richable r){
    		r.buy();
    	}
    	
    	public void shHappay(){
    		marry(()->{
    			this.buyHouse();
    		});
    		
    		marry(this::buyHouse);
    	}
    	
    	public static void main(String[] args){
    		new Husband().shHappay();
    	}
    }
    
    类的构造器引用
    public class Person{
        private String name;
    
        public Person(){}
        public Person(String name ){
            this.name=name;
        }
    
        public void setName(String name){
            this.name=name;
        }
        public String getName(){
            return name;
        }
        public String toString(){
            return "姓名"+name;
        }
    }
    
    public interface PersonBuilder {
        //根据名字返回Person类型
        public abstract Person builderPerson(String name);
    }
    
    
    public class Demo {
        public static void printName(String name,PersonBuilder pb){
            //传我一个姓名,返回一个Person对象
            Person person = pb.builderPerson(name);
            System.out.println(person.getName());
        }
    		//构造方法是已知的
        	//创建对象是已知的
        public static void main(String[] args){
            printName("迪丽热巴",(String name)->{
                return new Person(name);
            });
            printName("古力娜扎",Person::new);
        }
    }
    
    
    数组的构造器引用
    public interface ArrayBuilder {
        public abstract int[] builderArray(int length);
    }
    
    import java.util.Arrays;
    
    public class Demo1 {
        public static int[] createArray(int length,ArrayBuilder ab){
            return ab.builderArray(length);
        }
    
        public static void main(String[] args) {
            int[] arr1=createArray(10,(len)->{
               return new int[len];
            });
            System.out.println(arr1.length);
    
            int[] arr2 = createArray(10,int[]::new);
            System.out.println(Arrays.toString(arr2));
            System.out.println(arr2.length);
        }
    }
    
    
  • 相关阅读:
    线程池及其原理和使用
    多线程通信Queue
    Condition实现线程通信
    守护线程和锁
    习题 7:更多的打印
    习题 6:字符串和文本
    习题 5:更多的变量和打印
    习题 4:变量和命名
    习题 3:数字和数学计算
    习题 2:注解和#号
  • 原文地址:https://www.cnblogs.com/train99999/p/10947230.html
Copyright © 2020-2023  润新知