将Java代码重构为Java8 Stream 风格三则示例

将Java代码重构为Java8 Stream 风格三则示例

Java8的流风格写法,将for循环体除去,使得语义更加集中于逻辑的处理上,更加便于理解。  
这里博主自行写了三个示例,适合对Java8 stream有基本理解的编程者学习,算是抛砖引玉,希望大家能相互交流,如何能更加优雅的写出Stream风格。

示例1

    public class findAny {
    private static String[] strings = {"a", "b", "c", "c", "d", "e"};
    private static List<String> list = Arrays.asList(strings);
    private static Stream<String> stream = Stream.of(strings);

    private static String listWay(List<String> list) {
        String result = null;
        for (String s : list) {
            System.out.println("list+" + s);
            if (s.equals("c")) {
                System.out.println("done!");
                result = "c";
                break;
            }
        }
        return result;
    }

    private static String streamWay(Stream<String> stream) {
        return stream.peek(s1 -> System.out.println("stream+" + s1))
                .filter(s -> s.equals("c"))
                .peek(s2 -> System.out.println("done!"))
                .findFirst().orElse(null);

    }

这是最常见的for{...if{...break}}形式,equals()判断被等效为filter()break行为被等效为findFirst()。其实除了findFirst(),还有findAny()方法。二者在串行流下的行为应该是一致的,在并行流下findAny()的返回结果不一定。这里是博主自己的理解,如有错误,欢迎指正!

示例2

    public static int listWayCount(List<Ball> balls, String color){
        int count=0;
        for(Ball ball : balls){
            if(ball.getColor().equals(color)){
                count++;
            }
        }
        return count;
    }

    public static int streamWayCount(List<Ball> balls, String color){
        return (int) balls.stream().map(Ball::getColor)
                .filter(s -> s.equals(color))
                .count();
    }

这里是一个常见的对包含某种特殊属性的对象的不同来计数的形式。ball.getColor()等效为了map(Ball::getColor),stream中的包含对象由Ball变成了String;随后仍然是equals()等效为filter(),而count()方法则完成了for循环的count++

示例3

    public static Map<String, Float> legendWay(List<Ball> balls) {
        Map<String, Float> result = new HashMap<>();
        for(Ball ball : balls){
            if(!result.containsKey(ball.getColor())){
                result.put(ball.getColor(), 0f);
            }
            result.put(ball.getColor(),result.get(ball.getColor())+ball.getWeight());
        }
        return result;
    }

    public static Map<String, Float> java8Way(List<Ball> balls) {
        Map<String, Float> result = new HashMap<>();
        for (Ball ball : balls) {
            result.putIfAbsent(ball.getColor(), 0f);
            result.merge(ball.getColor(), ball.getWeight(), (acc, element) -> acc + element);
        }
        return result;
    }

    public static Map<String, Float> streamWay(List<Ball> balls) {
        Map<String, Float> result = new HashMap<>();
        balls.stream().collect(Collectors.groupingBy(Ball::getColor))
                .forEach((k, v) -> result.put(k, v.stream()
                        .map(Ball::getWeight)
                        .reduce(0f, ((acc, element) -> acc + element))));
        return result;
    }

    public static void main(String[] args){
        List<Ball> balls = Ball.randomBall(100);
        System.out.println(legendWay(balls));
        System.out.println(java8Way(balls));
        System.out.println(streamWay(balls));
    }

这个例子的区别是引入了map,但map并不支持stream的方法。这个例子的意思就是统计100个球中各种颜色球的总质量为多少。legendWay是传统写法,也是最糟糕的风格。java8Way是利用Java8中map增加的接口方法的一种写法,相对更加简洁。streamWay是首先利用了Collectors提供的分组方法,在对分组后的各种颜色的球执行map(),reduce(),统计出每种颜色球的总质量。

最后附上Ball的实现

public class Ball {
    private static final String[] colors = {"red", "blue", "green", "yellow", "pink", "pepper"};
    private static Random r = new Random();
    private String color;
    private float weight;

    private Ball() {
    }

    private Ball(String color,float weight) {
        this.color = color;
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public float getWeight() {
        return weight;
    }

    public static List<Ball> randomBall(int number) {
        List<Ball> balls = new ArrayList<>(number);
        for (int i = 0; i < number; i++) {
            Ball ball = new Ball(colors[r.nextInt(colors.length)],1f+r.nextFloat()/10f-0.05f);
            balls.add(ball);
        }
        return balls;
    }
}
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值