3年前 (2021-09-29)  Java系列 |   抢沙发  859 
文章评分 0 次,平均分 0.0

简洁高效的Eclipse Collections API

在本文中,您将了解Eclipse Collections集合提供的一些有用特性。您是否觉得Java Streams API有时还不够?我认为值得一看Eclipse集合。让我们讨论一下原因。

可变的或不变的

如果你喜欢Kotlin collections API,这个概念会吸引你。您可以创建可变和不可变集合。只有可变集合提供了添加新对象的方法。

Person p1 = new Person("Test1", 20);
Person p2 = new Person("Test2", 18);
Person p3 = new Person("Test3", 24);
MutableList<Person> persons = Lists.mutable.with(p1);
persons.add(p2);
persons.set(1, p3);

相同的方法不适用于例如ImmutableList并导致编译错误。

Person p1 = new Person("Test1", 20);
Person p2 = new Person("Test2", 18);
Person p3 = new Person("Test3", 24);
ImmutableList<Person> persons = Lists.immutable.with(p1);
persons.add(p2); // ERROR!
persons.set(1, p3); // ERROR!

Lazy collections(惰性集合)

Eclipse集合的另一个有趣特性称为惰性集合,它允许您将执行延迟到调用终端操作为止。您可以通过调用asLazy方法来启用lazy API。让我们看看它是如何工作的。首先,我们有以下类。我在getAge方法中添加了一条日志消息。

public class Person {

    private final String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        System.out.println("Age: " + this.age);
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

然后,让我们创建一个惰性集合。在第一步中,我们将每个人的年龄提高2岁。然后我们过滤20岁以上的人。最后,我们只从结果流中获得第一个元素。

Person p1 = new Person("Test1", 20);
Person p2 = new Person("Test2", 18);
Person p3 = new Person("Test3", 24);
Person p4 = new Person("Test4", 30);
Person p5 = new Person("Test5", 35);
MutableList<Person> persons = Lists.mutable.with(p1, p2, p3, p4, p5);
persons
   .asLazy()
   .tap(p -> p.setAge(p.getAge() + 2))
   .select(p -> p.getAge() > 20)
   .getFirst();

上面代码的输出是什么?因为我们只从列表中获取第一个元素,所以它只为第一个过滤对象调用getAge方法。

Age: 20
Age: 22

现在,让我们对非惰性集合执行相同的操作。

Person p1 = new Person("Test1", 20);
Person p2 = new Person("Test2", 18);
Person p3 = new Person("Test3", 24);
Person p4 = new Person("Test4", 30);
Person p5 = new Person("Test5", 35);
MutableList<Person> persons = Lists.mutable.with(p1, p2, p3, p4, p5);
persons
   .tap(p -> p.setAge(p.getAge() + 2))
   .select(p -> p.getAge() > 20)
   .getFirst();

这是结果。对于列表中的每个对象,我们调用getAge方法两次,尽管最后只调用第一个对象。

Age: 22
Age: 18
Age: 24
Age: 30
Age: 35
Age: 24
Age: 20
Age: 26
Age: 32
Age: 37

收集元素

使用Eclipse集合,我们可以使用单个方法轻松地收集和过滤元素。让我们考虑以下java流的操作。我们有组织的输入列表。然后我们只想筛选一个具有Test1名称的组织,从该组织中获取所有员工,然后将其转换为员工列表。

Employee e1 = new Employee(1, "Test1", "Developer");
Employee e2 = new Employee(2, "Test2", "Developer");
Employee e3 = new Employee(3, "Test3", "Developer");
Employee e4 = new Employee(4, "Test4", "Developer");
Organization o1 = new Organization("Test1", List.of(e1, e2));
Organization o2 = new Organization("Test2", List.of(e3, e4));
List<Organization> organizations = List.of(o1, o2);
List<Employee> employees = organizations
   .stream()
   .filter(o -> o.name().equals("Test1"))
   .map(Organization::employees)
   .flatMap(List::stream)
   .collect(Collectors.toList());

对于Eclipse集合,您可以使用以下两种方法执行相同的操作。

MutableList<Employee> employees = organizations
   .select(o -> o.name().equals("Test1"))
   .flatCollect(Organization::employees);

类似地,如果您希望收集员工而不使用Java Streams进行扁平化,则应按如下所示进行。

List<List<Employee>> employees2 = organizations
   .stream()
   .filter(o -> o.name().equals("Test1"))
   .map(Organization::employees)
   .collect(Collectors.toList());

另一方面,对于Eclipse集合,您可以使用单个方法collectIf来实现这一点。

MutableList<List<Employee>> employees2 = organizations
   .collectIf(o -> o.name().equals("Test1"), Organization::employees);

算术运算

使用Eclipse集合,我们可以轻松地进行一些算术运算,如计算或搜索mixmax元素。在下面的代码片段中,我们想计算一个职位开发人员的员工数量。

Employee e1 = new Employee(1, "Test1", "Developer");
Employee e2 = new Employee(2, "Test2", "Architect");
Employee e3 = new Employee(3, "Test3", "Developer");
Employee e4 = new Employee(4, "Test4", "Tester");
List<Employee> employees = List.of(e1, e2, e3, e4);
long c = employees
   .stream()
   .filter(emp -> emp.position().equals("Developer"))
   .count();

对于Eclipse集合,我们可以再次使用单个方法。

MutableList<Employee> employees = Lists.mutable.of(e1, e2, e3, e4);
int c = employees.count(emp -> emp.position().equals("Developer"));

类似地,Java流在列表中查找最小元素也有点复杂。我们希望找到id最低的员工。

Employee r1 = employees
   .stream()
   .min(Comparator.comparing(Employee::id))
   .orElseThrow(NoSuchElementException::new);

正如您可能猜到的,我们可以通过在Eclipse集合上调用单个方法来执行相同的操作。

Employee r1 = employees.minBy(Employee::id);

小结

我只描述了Eclipse集合提供的一些选定方法。有关整个API的详细说明,请参阅其文档。另一个可能说服您切换到Eclipse集合的原因是资源使用。在文档之后,它提供了集合、映射和其他基本集合的高效内存实现。另外,如果您对其他关于Java的文章感兴趣,您可以阅读Java8之后的新的开发人员友好特性。

官网地址:https://github.com/eclipse/eclipse-collections

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2391.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册