在本文中,您将了解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集合,我们可以轻松地进行一些算术运算,如计算或搜索mix
或max
元素。在下面的代码片段中,我们想计算一个职位开发人员的员工数量。
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
暂无评论