您当前的位置:首页 > 计算机 > 编程开发 > 编程箴言

在没有Lambda的年代

时间:02-05来源:作者:点击数:

自从有了Lambda,基本上就不会再写for循环,突然就有个想法,那以前没有Lambda的时候为什么每次操作集合的时候经常需要for循环呢?为什么就不封装一下呢?有了想法,那就想实现一下,参照Lambda的使用,写了一个过滤集合的实现,如下:

class ListUtil {
    /** 从集合中过滤出满足指定条件的元素 */
    public static <T> List<T> filter(List<T> list, Condition<T> condition) {
        List<T> resultList = new ArrayList<>();
        for (T item : list) {
            if (condition.isWant(item)) {
                // 如果此item是我们想要的,就加入到结果列表中
                resultList.add(item);
            }
        }
        return resultList;
    }
}

/** 条件 */
interface Condition<T> {
    /** 判断指定的item是否是我们想要的,如果是想要的就返回true,否则返回false */
    boolean isWant(T item);
}

没错,就是这么简单,一个工具类方法filter,一个接口类Condition,有了这两个东西,以后需要从集合中过滤元素的时候就再也不用写循环了,只需调用filter函数,传入一个集合,再传入一个过滤条件即可,过滤条件的功能就是用于指定你想要过滤什么样的元素,比如:有一个Person的列表,我想要过获取列表中所有姓张的人,代码如下:

public class Person {
    public String name;
    public int age;

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

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
}

List<Person> personList = new ArrayList<>();
personList.add(new Person("张三", 18));
personList.add(new Person("李四", 23));
personList.add(new Person("张小虎", 16));
personList.add(new Person("王五", 28));

如上代码,这是一个Person类,没什么好说的,我们还创建了一个Person的集合。接下来我们想过滤出这个集合中所有姓张的人,代码如下:

List<Person> resultList = ListUtil.filter(personList, new Condition<Person>() {
	@Override
	public boolean isWant(Person item) {
		return item.name.startsWith("张");
	}
});

System.out.println(resultList);

输出结果如下:

[Person{name='张三', age=18}, Person{name='张小虎', age=16}]

OK,成功实现我们需要的功能。接下来,我想找出所有年龄大于20岁的人,也不需要再写for循环了,代码如下:

List<Person> resultList = ListUtil.filter(personList, new Condition<Person>() {
	@Override
	public boolean isWant(Person item) {
		return item.age > 20;
	}
});

System.out.println(resultList);

输出结果如下:

[Person{name='李四', age=23}, Person{name='王五', age=28}]

OK,完美!不论过滤什么,我们都不需要再写循环语句了,只是写起来麻烦了一点,每次要创建一个Predicate对象,其实我们真正需要的就是一个判断语句而已,如:item.age > 20,所以在jdk1.8的时候出来的函数式接口就非常好用了,使用函数式接口修改如上代码,如下:

List<Person> resultList = ListUtil.filter(personList, item -> item.age > 20)

舒服!!当然,使用jdk1.8之后 我们就不需要自己去写filter函数,集合类中已经自带此函数。

有了这个经验,我们就可以实现更多的功能,比如从集合中查找满足指定条件的一个元素,代码如下:

class ListUtil {

    /** 从集合中找出满足指定条件的第一个元素 */
    public static <T> T find(List<T> list, Condition<T> condition) {
        for (T item : list) {
            if (condition.isWant(item)) {
                // 如果此item是我们想要的,就返回
                return item;
            }
        }
        return null;
    }
}

接下来,我们使用之前的personList集合,第一个年龄18岁的人,代码如下:

Person person = ListUtil.find(personList, new Condition<Person>() {
	@Override
	public boolean isWant(Person item) {
		return item.age == 18;
	 }
});

System.out.println(person);

输出如下:

Person{name='张三', age=18}

所以在没有Lambda的年代,我们没有这种思想,就经常做很多重复工作,其实这个模式不就是经典的策略设计模式么?相同的逻辑只写一次,不同的逻辑交由接口完成。以后在开发的时候,如果发现好几个地方代码好多重复的,但是有有一小部分不太一样,这时候就要使用策略模式了(不一定是for循环的代码),把不同的部分抽取成接口,相同的代码只写一次。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门