说到Stream流就让人想到I/O流,可谁又规定“流”就一定是I/O流呢?在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,这个Stream流可以解决目前集合存在的弊端。
这个Stream流可谓十分强大,你可能不知道他强在哪里,那是因为你没有写过接下来一段代码,让你体会没有它之前,操作集合之困难,你会感叹的。
题目
现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)依次进行以下若干操作步骤:
- 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
- 第一个队伍筛选之后只要前3个人;存储到一个新集合中。
- 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
- 第二个队伍筛选之后不要前2个人;存储到一个新集合中。
- 将两个队伍合并为一个队伍;存储到一个新集合中。
- 根据姓名创建 Person 对象;存储到一个新集合中。
- 打印整个队伍的Person对象信息
public class DemoArrayListNames {
public static void main(String[] args) {
//第一支队伍
ArrayList<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("石破天");
one.add("石中玉");
one.add("老子");
one.add("庄子");
one.add("洪七公");
//第二支队伍
ArrayList<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("赵丽颖");
two.add("张三丰");
two.add("尼古拉斯赵四");
two.add("张天爱");
two.add("张二狗");
// 第一个队伍只要名字为3个字的成员姓名;
List<String> oneA = new ArrayList<>();
for (String name : one) {
if (name.length() == 3) {
oneA.add(name);
}
}
// 第一个队伍筛选之后只要前3个人;
List<String> oneB = new ArrayList<>();
for (int i = 0; i < 3; i++) {
oneB.add(oneA.get(i));
}
// 第二个队伍只要姓张的成员姓名;
List<String> twoA = new ArrayList<>();
for (String name : two) {
if (name.startsWith("张")) {
twoA.add(name);
}
}
// 第二个队伍筛选之后不要前2个人;
List<String> twoB = new ArrayList<>();
for (int i = 2; i < twoA.size(); i++) {
twoB.add(twoA.get(i));
}
// 将两个队伍合并为一个队伍;
List<String> totalNames = new ArrayList<>();
totalNames.addAll(oneB);
totalNames.addAll(twoB);
// 根据姓名创建Person对象;
List<Person> totalPersonList = new ArrayList<>();
for (String name : totalNames) {
totalPersonList.add(new Person(name));
}
// 打印整个队伍的Person对象信息。
for (Person person : totalPersonList) {
System.out.println(person);
}
}
}
结果为
Person{name='宋远桥'}
Person{name='苏星河'}
Person{name='石破天'}
Person{name='张天爱'}
Person{name='张二狗'}
现在我们使用Stream流来解决
public class Stream2Demo {
public static void main(String[] args) {
Stream<String> stream1=Stream.of("迪丽热巴","宋远桥","苏星河","石破天","老子","庄子","洪七公");
// 只要名字为三个字且取集合前三个元素
Stream<String> stream2=stream1.filter(name->name.length()==3).limit(3);
Stream<String> stream3=Stream.of("古力娜扎","张无忌","赵丽颖","张三丰","尼古拉斯赵四","张天爱","张二狗");
// 只要名字以“张”开头,前两个元素跳过
Stream<String> stream4=stream3.filter(name->name.startsWith("张")).skip(2);
// 将两个stream合并为一个流
Stream<String> stream5=Stream.concat(stream2, stream4);
ArrayList<Person> list=new ArrayList<>();
// 遍历整个流中的元素并添加进集合
stream5.forEach(e->list.add(new Person(e)));
System.out.println(list);// 结果和上述一样
}
}
还有很多方法的作用,小伙伴们可以自行查阅API去一个个尝试,它是可以链式编程的,但是有个注意事项时在“终结方法”不可以再写“延迟方法”,因为那时候流已经关闭了。
延迟方法:返回值类型仍然是stream接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为延迟方法);
终结方法:返回值类型不再是stream接口自身类型的方法,因此不再支持类似StringBuilder那样的链式调用。比如count、forEach。