java8新特性----Stream

本文详细介绍了Java8的新特性,特别是Stream API的使用,包括如何获取流、执行终端操作如forEach、count、max/min等,以及中间操作如filter、map、sorted、limit和skip。同时,文章还深入探讨了核心的函数式接口,如Consumer、Supplier、Function、Predicate以及BiFunction,通过实例解析其底层源码和应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、核心函数式接口

(1)、Consumer

消费型接口 ,传递参数,使用参数做一个处理。没有返回值

底层源码

@FunctionalInterface
public interface Consumer<T> {
    void accept(T var1);

    default Consumer<T> andThen(Consumer<? super T> var1) {
        Objects.requireNonNull(var1);
        return (var2) -> {
            this.accept(var2);
            var1.accept(var2);
        };
    }
}

案例

public static void main(String[] args) {
		String str = "Hello World";
		Consumer<String> consumer = (String s) -> {
				str.length();
			};

	consumer.accept(str);
		
	}

//======================================
public static void main(String[] args) {
		String str = "Hello world";
		Consumer<String> c1 = ((String s1 )-> System.out.println(s1.length()));
		Consumer<String> mc1 = (String s1)->{
			System.out.println(s1.length());
		};
		Consumer<String> mc2 = (String s1)->{
			System.out.println(s1.toUpperCase());
		};
		Consumer<String> mc3 = s1->{
			System.out.println(s1.substring(0,5));
		};
//		mc2.accept(str);
		mc1.andThen(mc2.andThen(mc3)).accept(str);

(2)、Supplier

供给型接口, 无需要传递参数,返回对象

底层源码

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

案例

public static void main(String[] args) {
		Supplier<Integer> supplier = ()->{
			return new Random(10).nextInt();
		};
		int random = supplier.get();
		System.out.println(random);
	}

(3)、Function

功能型接口,需要传递参数,根据参数做处理,将处理结果返回

底层源码

@FunctionalInterface
public interface Function<T, R> {
    R apply(T var1);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> var1) {
        Objects.requireNonNull(var1);
        return (var2) -> {
            return this.apply(var1.apply(var2));
        };
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> var1) {
        Objects.requireNonNull(var1);
        return (var2) -> {
            return var1.apply(this.apply(var2));
        };
    }

    static <T> Function<T, T> identity() {
        return (var0) -> {
            return var0;
        };
    }
}

案例

String s = "Hello World" ;
//需要实现功能,将字符串转换成大小
Function<String,String> f1 = (String s1)->{
    System.out.println("1操作");
    return s1.toUpperCase();
};
//System.out.println( f1.apply(s) );

Function<String,String> f2 = s1->{
    System.out.println("2操作");
    return s1.substring(0,3);
};

//f1处理后,再进行一次f2的处理
//System.out.println( f1.andThen(f2).apply(s) );
//f1处理前,先进行一次f2的处理
System.out.println( f1.compose(f2).apply(s) );

(4)、Predicate

断言型接口,传递参数,根据参数做判断,返回boolean

底层源码

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T var1);

    default Predicate<T> and(Predicate<? super T> var1) {
        Objects.requireNonNull(var1);
        return (var2) -> {
            return this.test(var2) && var1.test(var2);
        };
    }

    default Predicate<T> negate() {
        return (var1) -> {
            return !this.test(var1);
        };
    }

    default Predicate<T> or(Predicate<? super T> var1) {
        Objects.requireNonNull(var1);
        return (var2) -> {
            return this.test(var2) || var1.test(var2);
        };
    }

    static <T> Predicate<T> isEqual(Object var0) {
        return null == var0 ? Objects::isNull : (var1) -> {
            return var0.equals(var1);
        };
    }

案例

public static void main(String[] args) {
		User user = new User("zn","123");
		Predicate<User> predicate = (User user1) ->{
			return user1.uname.equals("zn")  && user1.upass.equals("123");
		};
		predicate.test(user);
	}

(5)、扩展: BiFunction

可以进行计算

底层源码:

@FunctionalInterface
public interface BiFunction<T, U, R> {
    R apply(T var1, U var2);

    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> var1) {
        Objects.requireNonNull(var1);
        return (var2, var3) -> {
            return var1.apply(this.apply(var2, var3));
        };
    }
}

案例

public static void main(String[] args) {
		BiFunction<Integer,Integer,Integer> bi = (a,b) -> {
			return a+b;
		};
		System.out.println(bi.apply(5,10));
	}

二、Stream

获取流

list.stream();
set.stream();
collection.stream();
//================
Stream.of(1,2,3,4,5);
//====================================
//获取limit方法中传入的参数个
Stream.generate(()->"Hello").limit(100);
//============================================
//第一个参数是新流中的初始元素,
//然后使用该数据做第二个参数也就是UnaryOperator函数的入参去计算第二元素,
//然后把新计算得到的第二个元素作为入参继续计算第三个元素,以此循环可以制造无限个元素
Stream.iterate(1,(i)->++i).limit(100)

终端操作

这种操作会产生一个结果的,如果一个流被消费过了,那它就不能被重用的。

forEach()

public static void main(String[] args) {
		List<Car> cars = Arrays.asList(
				new Car("宝马","蓝色",300000),
				new Car("奔驰","黑色",400000),
				new Car("奥迪","红色",450000),
				new Car("保时捷","蓝色",600000),
				new Car("本田","白色",2000000),
				new Car("比亚迪","白色",220000),
				new Car("理想","黑色",250000)
		);
		cars.stream().forEach(car -> System.out.println(car));
		// --------------    等价于  ----------->   
		cars.stream().forEach(System.out::println);
	}

count

long count = cars.stream().count();
		System.out.println(count);

max,min

Optional<Car> max = cars.stream().max((car1, car2) -> car1.getPrice() - car2.getPrice());
		System.out.println(max.toString());
Optional<Car> max = cars.stream().min((car1, car2) -> car1.getPrice() - car2.getPrice());
		System.out.println(min.toString());	

汇总

IntSummaryStatistics collect = cars.stream().collect(
										Collectors.summarizingInt(car -> car.getPrice()));
		System.out.println(collect);

分组

Map<String, List<Car>> collect1 = cars.stream().collect(Collectors.groupingBy(car ->car.getColor()));
		System.out.println(collect1);

中间操作

中间操作可以用来创建执行一系列动作的管道。

中间操作不是立即发生的。相反,当在中间操作创建的新流上执行完终端操作后,中间操作指定的操作才会发生。所以中间操作是延迟发生的,中间操作的延迟行为主要是让流API能够更加高效地执行。

filter

cars.stream()
    .filter(car->"黑色".equals(car.color))
    .forEach(System.out::println);

map

		cars.stream().map(car -> {
			return new Car(car.getName(), car.getPrice());
		}).forEach(System.out::println);

sorted()

//排序
cars.stream()
    .sorted((c1,c2)->c1.price-c2.price)
    .forEach(System.out::println);

limit() & skip()

//分页,从那条记录开始,取几条记录, 从0开始取3条(0,1,2),从3开始取3条(3,4,5),从6开始取3条(7,8,9)
cars.stream()
    .sorted((c1,c2)->c1.price-c2.price)
    .skip(4) //跳过几个,因为时从0开始条,这个条过几个,也可以理解为从第几个开始
    .limit(3)
    .forEach(System.out::println);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值