ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

在Java流中拆分对象

2019-06-12 01:59:07  阅读:242  来源: 互联网

标签:java java-8 java-stream method-reference


我想知道是否可以在流内拆分对象.例如,对于此员工:

public class Employee {

    String name;
    int age;
    double salary;

    public Employee(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName() { return name; }

    public int getAge() { return age; }

    public double getSalary() { return salary; }
}

我想在流中执行一些操作.为简单起见,让它像这样(假设我的代码架构不允许将它放在Employee类中 – 否则它会太容易了):

public void someOperationWithEmployee(String name, int age, double salary) {
    System.out.format("%s %d %.0f\n", name, age, salary);
}

现在它看起来像这样:

Stream.of(new Employee("Adam", 38, 3000), new Employee("John", 19, 2000))
        // some conversations go here ...
        .forEach(e -> someOperationWithEmployee(e.getName, e.getAge(), e.getSalary));

问题是 – 是否可以将一些代码放在流中?

Stream.of(new Employee("Adam", 38, 3000), new Employee("John", 19, 2000))
        // some conversations go here
        .forEach((a, b, c) -> someOperationWithEmployee(a, b, c));

我想要实现的目标是什么? – 我想如果我可以映射一些对象字段然后处理像.forEach(this :: someOperationWithEmployee)那样的代码可读性会略有提高.

2015年5月14日更新

毫无疑问,将Employee对象传递给someOperationWithEmployee在这种情况下是最漂亮的解决方案,但有时我们不能在现实生活中做到这一点,并且应该是lambdas的通用解决方案.

解决方法:

我不确定这是否适合您的需求,但它有点反复,而不是检查某些类型.

您可以这样运行我的解决方案:

    Stream.of(new Employee("Adam", 38, 3000), new Employee("John", 19, 2000))
        .forEach(
                e->ArrayCaller.<TriConsumer<String, Integer, Double>>convert(e::getName, e::getAge, e::getSalary)
                                                                     .call((a, b, c) -> operation(a, b, c)));

它会称这个’main’类的简单方法:

private void operation(String name, int age, double salary) {
    System.out.format("%s %d %.0f\n", name, age, salary);
}

当然它需要这种辅助类型:

/** Extending interfaces must have a method called consume with N args */
interface NConsumer {}

/*
 * Method must be called consume for reflection.
 *
 * You can define N interfaces like this.
 */
nterface TriConsumer<A, B, C> extends NConsumer {
    void consume(A a, B b, C c);
}

interface ArrayCaller<E extends NConsumer> {
    void call(E code);
    static <T extends NConsumer> ArrayCaller<T> convert(Supplier<?>...argSuppliers) {
        final Object[] args = new Object[argSuppliers.length];
        for (int i = 0; i < argSuppliers.length; i++) {
            args[i] = argSuppliers[i].get();
        }
        return new ArrayCaller<T>() {
            @Override
            public void call(T code) {
                for (Method m: code.getClass().getMethods()) {
                    if (m.getName().equals("consume")) {
                        try {
                            m.invoke(code, args);
                        } catch (IllegalAccessException
                                | IllegalArgumentException
                                | InvocationTargetException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        };
    }
}

标签:java,java-8,java-stream,method-reference
来源: https://codeday.me/bug/20190612/1222699.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有