1. 概述

本手册采用精炼的配方式结构,通过聚焦的代码片段展示如何使用Guava的函数式核心组件——Predicate(断言)和Function(函数)。手册风格直击要点,省略冗余说明,专为实战场景设计。

2. 实用手册

2.1 按条件过滤集合(自定义Predicate)

List<Integer> numbers = Lists.newArrayList(1, 2, 3, 6, 10, 34, 57, 89);
Predicate<Integer> acceptEven = new Predicate<Integer>() {
    @Override
    public boolean apply(Integer number) {
        return (number % 2) == 0;
    }
};
List<Integer> evenNumbers = Lists.newArrayList(Collections2.filter(numbers, acceptEven));
Integer found = Collections.binarySearch(evenNumbers, 57);
assertThat(found, lessThan(0));

2.2 过滤集合中的null值

List<String> withNulls = Lists.newArrayList("a", "bc", null, "def");
Iterable<String> withoutNuls = Iterables.filter(withNulls, Predicates.notNull());
assertTrue(Iterables.all(withoutNuls, Predicates.notNull()));

2.3 检查集合所有元素是否满足条件

List<Integer> evenNumbers = Lists.newArrayList(2, 6, 8, 10, 34, 90);
Predicate<Integer> acceptEven = new Predicate<Integer>() {
    @Override
    public boolean apply(Integer number) {
        return (number % 2) == 0;
    }
};
assertTrue(Iterables.all(evenNumbers, acceptEven));

2.4 取反Predicate条件

List<Integer> evenNumbers = Lists.newArrayList(2, 6, 8, 10, 34, 90);
Predicate<Integer> acceptOdd = new Predicate<Integer>() {
    @Override
    public boolean apply(Integer number) {
        return (number % 2) != 0;
    }
};
assertTrue(Iterables.all(evenNumbers, Predicates.not(acceptOdd)));

2.5 应用简单函数转换

List<Integer> numbers = Lists.newArrayList(1, 2, 3);
List<String> asStrings = Lists.transform(numbers, Functions.toStringFunction());
assertThat(asStrings, contains("1", "2", "3"));

2.6 通过中间函数排序集合

List<Integer> numbers = Arrays.asList(2, 1, 11, 100, 8, 14);
Ordering<Object> ordering = Ordering.natural().onResultOf(Functions.toStringFunction());
List<Integer> inAlphabeticalOrder = ordering.sortedCopy(numbers);
List<Integer> correctAlphabeticalOrder = Lists.newArrayList(1, 100, 11, 14, 2, 8);
assertThat(correctAlphabeticalOrder, equalTo(inAlphabeticalOrder));

2.7 复杂场景:链式组合Predicate和Function

List<Integer> numbers = Arrays.asList(2, 1, 11, 100, 8, 14);
Predicate<Integer> acceptEvenNumber = new Predicate<Integer>() {
    @Override
    public boolean apply(Integer number) {
        return (number % 2) == 0;
    }
};
Function<Integer, Integer> powerOfTwo = new Function<Integer, Integer>() {
    @Override
    public Integer apply(Integer input) {
        return (int) Math.pow(input, 2);
    }
};

FluentIterable<Integer> powerOfTwoOnlyForEvenNumbers = 
FluentIterable.from(numbers).filter(acceptEvenNumber).transform(powerOfTwo);
assertThat(powerOfTwoOnlyForEvenNumbers, contains(4, 10000, 64, 196));

2.8 组合两个函数

List<Integer> numbers = Arrays.asList(2, 3);
Function<Integer, Integer> powerOfTwo = new Function<Integer, Integer>() {
    @Override
    public Integer apply(Integer input) {
        return (int) Math.pow(input, 2);
    }
};
List<Integer> result = Lists.transform(numbers, 
    Functions.compose(powerOfTwo, powerOfTwo));
assertThat(result, contains(16, 81));

2.9 创建基于Set和Function的Map

Function<Integer, Integer> powerOfTwo = new Function<Integer, Integer>() {
    @Override
    public Integer apply(Integer input) {
        return (int) Math.pow(input, 2);
    }
};
Set<Integer> lowNumbers = Sets.newHashSet(2, 3, 4);

Map<Integer, Integer> numberToPowerOfTwoMuttable = Maps.asMap(lowNumbers, powerOfTwo);
Map<Integer, Integer> numberToPowerOfTwoImuttable = Maps.toMap(lowNumbers, powerOfTwo);
assertThat(numberToPowerOfTwoMuttable.get(2), equalTo(4));
assertThat(numberToPowerOfTwoImuttable.get(2), equalTo(4));

2.10 将Predicate转换为Function

List<Integer> numbers = Lists.newArrayList(1, 2, 3, 6);
Predicate<Integer> acceptEvenNumber = new Predicate<Integer>() {
    @Override
    public boolean apply(Integer number) {
        return (number % 2) == 0;
    }
};
Function<Integer, Boolean> isEventNumberFunction = Functions.forPredicate(acceptEvenNumber);
List<Boolean> areNumbersEven = Lists.transform(numbers, isEventNumberFunction);

assertThat(areNumbersEven, contains(false, true, false, true));

3. 更多Guava实用手册

Guava是个功能强大且极其实用的库,这里推荐其他API的实用手册:

祝使用愉快!

4. 总结

这种手册形式与常规教程不同——本质是我长期维护的内部开发笔记。目标是将这些实用技巧在线共享,并在遇到新案例时持续补充。

所有示例代码**均可在GitHub项目**中找到,基于Maven构建,可直接导入运行。


原始标题:Guava Functional Cookbook

» 下一篇: Mockito Verify用法