假设有以下字符串 "1"
,"2"
,"123"
,"234"
,"12345"
,我们想要获得长度大于4的字符串。以下提供两种写法.
import java.util.ArrayList; public class Demo { public static void main(String[] args) { // 创建一个集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<String>(); // 创建新集合,用来存储过滤后的字符串元素 ArrayList<String> newList = new ArrayList<String>(); list.add("1"); list.add("2"); list.add("123"); list.add("234"); list.add("12345"); // 把长度大于4的字符串存储 for(String s:list) { if(s.length()>4) newList.add(s); } // 输出 newList for(String s:newList){ System.out.println(s); } } }
import java.util.ArrayList; public class Demo { public static void main(String[] args) { // 创建一个集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<String>(); list.add("1"); list.add("2"); list.add("123"); list.add("234"); list.add("12345"); // Stream 流写法 list.stream().filter(s -> s.length() > 4).forEach(System.out::println); } }
好处:
1. 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义
2. Stream流把真正的函数式编程风格引入到Java中
3. 可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码
4. 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象
import java.util.*; import java.util.stream.Stream; public class Demo { public static void main(String[] args) { //Collection体系的集合可以使用默认方法stream()生成流 List<String> list = new ArrayList<String>(); Stream<String> listStream = list.stream(); Set<String> set = new HashSet<String>(); Stream<String> setStream = set.stream(); //Map体系的集合间接的生成流 Map<String,Integer> map = new HashMap<String, Integer>(); Stream<String> keyStream = map.keySet().stream(); Stream<Integer> valueStream = map.values().stream(); Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream(); //数组可以通过Stream接口的静态方法of(T... values)生成流 String[] strArray = {"hello","world","java"}; Stream<String> strArrayStream = Stream.of(strArray); Stream<String> strArrayStream2 = Stream.of("hello", "world", "java"); Stream<Integer> intStream = Stream.of(10, 20, 30); } }
方法名 | 说明 |
---|---|
Stream filter(Predicate predicate) | 用于对流中的数据进行过滤 |
Stream limit(long maxSize) | 返回此流中的元素组成的流,截取前指定参数个数的数据 |
Stream skip(long n) | 跳过指定参数个数的数据,返回由该流的剩余元素组成的流 |
static Stream concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
Stream distinct() | 返回由该流的不同元素(根据Object.equals(Object) )组成的流 |
Stream sorted() | 返回由此流的元素组成的流,根据自然顺序排序 |
Stream sorted(Comparator comparator) | 返回由该流的元素组成的流,根据提供的Comparator进行排序 |
Stream map(Function mapper) | 返回由给定函数应用于此流的元素的结果组成的流 |
IntStream mapToInt(ToIntFunction mapper) | 返回一个IntStream其中包含将给定函数应用于此流的元素的结果 |
import java.util.ArrayList; public class Demo { public static void main(String[] args) { //创建一个集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<String>(); list.add("黄晓明"); list.add("张三"); list.add("张无忌"); list.add("李子明"); list.add("樊星辰"); list.add("李双双"); // 把list集合中以张开头的元素在控制台输出 list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println); System.out.println("--------"); // 把list集合中长度为3的元素在控制台输出 list.stream().filter(s -> s.length() == 3).forEach(System.out::println); System.out.println("--------"); // 把list集合中以张开头的,长度为3的元素在控制台输出 list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println); } }
import java.util.ArrayList; public class Demo { public static void main(String[] args) { // 创建一个集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<String>(); list.add("黄晓明"); list.add("张三"); list.add("张无忌"); list.add("李子明"); list.add("樊星辰"); list.add("李双双"); // 取前3个数据在控制台输出 list.stream().limit(3).forEach(System.out::println); System.out.println("--------"); // 跳过3个元素,把剩下的元素在控制台输出 list.stream().skip(3).forEach(System.out::println); System.out.println("--------"); // 跳过2个元素,把剩下的元素中前2个在控制台输出 list.stream().skip(2).limit(2).forEach(System.out::println); } }
import java.util.ArrayList; import java.util.stream.Stream; public class Demo { public static void main(String[] args) { // 创建一个集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<String>(); list.add("黄晓明"); list.add("张三"); list.add("张无忌"); list.add("李子明"); list.add("樊星辰"); list.add("李双双"); // 取前4个数据组成一个流 Stream<String> s1 = list.stream().limit(4); // 跳过2个数据组成一个流 Stream<String> s2 = list.stream().skip(2); // 合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复 Stream.concat(s1,s2).distinct().forEach(System.out::println); } }
import java.util.ArrayList; import java.util.stream.Stream; public class Demo { public static void main(String[] args) { // 创建一个集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<String>(); list.add("huangxiaoming"); list.add("zhangsan"); list.add("zhangwuji"); list.add("liziming"); list.add("fanxingchen"); list.add("lishuangshuang"); // 按照字母顺序把数据在控制台输出 list.stream().sorted().forEach(System.out::println); //按照字符串长度把数据在控制台输出 list.stream().sorted((s1,s2) -> { int num = s1.length()-s2.length(); int num2 = num==0?s1.compareTo(s2):num; return num2; }).forEach(System.out::println); } }
import java.util.ArrayList; public class Demo { public static void main(String[] args) { //创建一个集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<String>(); list.add("10"); list.add("20"); list.add("30"); list.add("40"); list.add("50"); // 将集合中的字符串数据转换为整数之后在控制台输出 // list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println); // list.stream().map(Integer::parseInt).forEach(System.out::println); // list.stream().mapToInt(Integer::parseInt).forEach(System.out::println); //int sum() 返回此流中元素的总和 int result = list.stream().mapToInt(Integer::parseInt).sum(); System.out.println(result); } }
终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作。
方法名 | 说明 |
---|---|
void forEach(Consumer action) | 对此流的每个元素执行操作 |
long count() | 返回此流中的元素数 |
import java.util.ArrayList; import java.util.stream.Stream; public class Demo { public static void main(String[] args) { // 创建一个集合,存储多个字符串元素 ArrayList<String> list = new ArrayList<String>(); list.add("黄晓明"); list.add("张三"); list.add("张无忌"); list.add("李子明"); list.add("樊星辰"); list.add("李双双"); // 把集合中的元素在控制台输出 // list.stream().forEach(System.out::println); // 统计集合中有几个以张开头的元素,并把统计结果在控制台输出 long count = list.stream().filter(s -> s.startsWith("张")).count(); System.out.println(count); } }
对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中。
方法名 | 说明 |
---|---|
R collect(Collector collector) | 把结果收集到集合中 |
方法名 | 说明 |
---|---|
public static Collector toList() | 把元素收集到List集合中 |
public static Collector toSet() | 把元素收集到Set集合中 |
public static Collector toMap(Function keyMapper,Function valueMapper) | 把元素收集到Map集合中 |
import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; public class Demo { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>(); list.add("小红"); list.add("小明"); list.add("小王"); list.add("小蓝"); // 得到名字为3个字的流 Stream<String> listStream = list.stream().filter(s -> s.length() == 3); // 把使用Stream流操作完毕的数据收集到List集合中并遍历 List<String> names = listStream.collect(Collectors.toList()); for(String name : names) { System.out.println(name); } //创建Set集合对象 Set<Integer> set = new HashSet<Integer>(); set.add(10); set.add(20); set.add(37); set.add(31); set.add(35); // 得到年龄大于25的流 Stream<Integer> setStream = set.stream().filter(age -> age > 25); // 把使用Stream流操作完毕的数据收集到Set集合中并遍历 Set<Integer> ages = setStream.collect(Collectors.toSet()); for(Integer age : ages) { System.out.println(age); } //定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成 String[] strArray = {"小红,20", "小明,29", "小王王,33", "小白,25"}; // 得到字符串中年龄数据大于28的流 Stream<String> arrayStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28); // 把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,年龄作值 Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1]))); Set<String> keySet = map.keySet(); for (String key : keySet) { Integer value = map.get(key); System.out.println(key + "," + value); } } }