Java8流处理代码总结

package com.dong.java8;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.partitioningBy;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
 * 关于Java8中流的定义,操作的方法汇总
 * 
 * @author Liudong
 */
public class testStream {
	static List<Dish> menu = Arrays.asList(
			new Dish("pork",false,800,Dish.Type.MEAT),
			new Dish("beef",false,700,Dish.Type.MEAT),
			new Dish("chichken",false,400,Dish.Type.MEAT),
			new Dish("french fries",true,530,Dish.Type.OTHER),
			new Dish("rice",true,350,Dish.Type.OTHER),
			new Dish("season fruit",true,120,Dish.Type.OTHER),
			new Dish("pizza",true,550,Dish.Type.OTHER),
			new Dish("prawns",false,300,Dish.Type.FISH),
			new Dish("salmon",false,450,Dish.Type.FISH)
			);
	public static void useSteam() {
		List<String> ThreeHighCaloricDishNames = menu.stream()
										 .filter( d -> d.getCalories() > 300) //Java编译器会从上下文中推断出用什么函数式接口来配合lambda表达式,即可以推断出合适的lambda签名
										 .map( d -> d.getName())
										 .limit(3)
										 .collect(toList());
		//stream():得到一个流
		//filter,map,limit对流的操作,返回另一个流
		//collect,返回一个结果
		
		//lambda使用的条件是函数式接口,而filter接受一个Predicted函数接口,Predicted函数式接口已经由系统帮我们实现,
		//这里的d.getCalories()是行为的实现过程中,我们使用的一个外部方法,和函数式接口无关;这里的d.getCalories()>300只是行为而已;
		//不可混淆以为Dish需要提供一个函数接口。。。;
		System.out.println(ThreeHighCaloricDishNames);
	}
	//limit, map
	public static void midleOperator() {
		List<String> names =
				menu.stream()
				.filter(d -> {
					System.out.println("filtering " + d.getName());
					return d.getCalories()>300;
				})
				.map(d -> {
					System.out.println("mapping " + d.getName());
					return d.getName();
				})
				.limit(3)
				.collect(toList());
		System.out.println(names);
	}
	//distinct
	public static void distincttest() {
		List<Integer> numbers = Arrays.asList(1,2,1,3,3,1,2,5,8,200);
		numbers.stream()
			   .filter( i -> i % 2 == 0)
			   .distinct()
			   .forEach(System.out::println);

	}
	//映射:map,map方法会接受一个函数作为参数,这个函数会被映射到每个元素上,并将其映射为一个新的元素;
	public static  void toMapping() {
		// TODO Auto-generated method stub
		List<String> dishName = menu.stream()
				.map(Dish::getName)
				.collect(toList());
	}
	public static void toMultipMapping() {
		List<String> words =Arrays.asList("hello","world");
		//使用map,返回的流是一个整体,即Stream<String[]>类型的,里面的元素为  0号元素为 hello,1号元素为world;
		List<String[]> Characters = words.stream()
				.map(word -> word.split(""))
				.distinct()
				.collect(toList());
		
		System.out.println(Characters);
		
		//使用flatMap,将数组映射成流的内容;
		List<String> uniqueCharacters = words.stream()
				.map(word -> word.split(""))
				.flatMap(Arrays::stream)
				.distinct()
				.collect(Collectors.toList());
		
		System.out.println(uniqueCharacters);	
	}
	//anyMatch方法返回一个boolean,检查行为至少匹配一个元素,是终端操作 ;
	//allMatch方法返回一个boolean,检查行为是否全部满足要求,是终端操作;
	//noneMath方法返回一个boolean,检查行为是否没有一个元素u,是终端操作;
	public static void anyMatch() {
		// TODO Auto-generated method stub
		if(menu.stream().anyMatch(Dish::isVegetarian)) {
			System.out.println("The menu is vegetarian friendsly");
		}
		if(menu.stream().allMatch(d -> d.getCalories() < 500)) {
			System.out.println("the all menu is lg 1000");
		}
		if(menu.stream().noneMatch(d -> d.getCalories() >=1000)) {
			System.out.println("no  match");
		}
	}
	//寻找第一个元素
	public static void findElement() {
		// TODO Auto-generated method stub
		List<Integer> number = Arrays.asList(1,2,3,4,5);
		Optional<Integer> firstSquareDivisibleByThree = 
				number.stream()
				.map(x -> x* x)
				.filter(x -> x % 3 == 0)
				.findFirst();
		System.out.println(firstSquareDivisibleByThree);
	}
	//归约: reduce操作将流流中所有元素反复结合起来,得到一个值;
	public static  void toSum() {
		// TODO Auto-generated method stub
		List<Integer> number = Arrays.asList(1,2,3,4,5);
		int  sum = number.stream().reduce(0, (a,b) -> a + b);
		System.out.println(sum);
	}
	//数值流
	//mapToInt会从没到菜中提取热量,并返回一个IntStream,然后可以调用IntStream接口中定义的sum方法;
	public static void valueStream() {
		int calories = menu.stream()
				.mapToInt(Dish::getCalories)
				.sum();
		
		//将数值流在转换会对象流
		IntStream inStream = menu.stream().mapToInt(Dish::getCalories);
		Stream<Integer> stream = inStream.boxed();
		
		System.out.println(calories);
	}
	//构建流
	public void constructStream() {
		//由值创建流
		Stream<String> stream = Stream.of("java " ,"c++","python","c","vb");
		stream.map(String::toUpperCase).forEach(System.out::println);
		//由数组创建流
		int [] numbers = {1,2,3,9,10};
		int sum = Arrays.stream(numbers).sum();
		//由文件生成流
		long uniqueWords = 0;
		try(Stream<String> lines = Files.lines(Paths.get("data.txt"),Charset.defaultCharset())){
			uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
					.distinct()
					.count();
		}catch(IOException e) {	
		}
		//无限流
		//iterate方法接受一个初始值,还有一个依次应用在每个产生的新值上的Lambda,
		Stream.iterate(0, n -> n+2)
		      .limit(10)
		      .forEach(System.out::println);
		//generate方法,接受一个Supplier<T> 类型的Lambda提供的新值;
		Stream.generate(Math::random)
		      .limit(10)
		      .forEach(System.out::println);
	}
	public enum CaloricLevel {DIET,NORMAL,FAT};
	//分组
	public static void toGroupingBy() {
		//一级分类
		Map<CaloricLevel,List<Dish>> dishesByCaloricLevel = menu.stream().collect(
				groupingBy(dish->{
					if(dish.getCalories() <= 400) return CaloricLevel.DIET;
					else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
					else return CaloricLevel.FAT;
				}));
		System.out.println(dishesByCaloricLevel);
		//多级分类
		Map<Dish.Type,Map<CaloricLevel,List<Dish>>> dishesByTypeCaloricLevel = 
				menu.stream().collect(
					groupingBy(Dish::getType,
							groupingBy(dish -> {
								if(dish.getCalories() <= 400) return CaloricLevel.DIET;
								else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
								else return CaloricLevel.FAT;
							})));
		System.out.println(dishesByTypeCaloricLevel);
	}
	//分类
	public static void classcify() {
		//分区:是分组的特殊情况,有一个谓词最为分类函数,分区函数返回一个布尔值,意味着得到的分组Map的键类型是boolean;最多可以分为两组
		Map<Boolean,List<Dish>> partitionedMenu = 
				menu.stream().collect(partitioningBy(Dish::isVegetarian));
		System.out.println(partitionedMenu);
	}
	public static void main(String[] args) {
		//testStream.useSteam();
		//testStream.midleOperator();
		//testStream.distincttest();
		//toMultipMapping();
		//anyMatch();
		//findElement();
		//toSum();
		//valueStream();
		//toGroupingBy();
		//classcify();
	}
	
}

package com.dong.java8;

public class Dish {
	
	private final String name;
	private final boolean vegetarian;
	private final int calories;
	private final Type type;
		
	public Dish(String name, boolean vegetarian, int calories, Type type) {
		super();
		this.name = name;
		this.vegetarian = vegetarian;
		this.calories = calories;
		this.type = type;
	}
	
	public enum Type{MEAT,FISH,OTHER};
	
	public String getName() {
		return name;
	}
	public boolean isVegetarian() {
		return vegetarian;
	}
	public int getCalories() {
		return calories;
	}
	public Type getType() {
		return type;
	};
	
	
	
}

代码参考:《Java8实战》中的片段 作者:Raoul-Gabriedl Urma Mario Fusco Alan Mycroft  ,,由衷感谢此书作者为我们提供学习内容

全部评论

相关推荐

02-07 12:06
已编辑
华侨大学 测试开发
最近看到很多&nbsp;92&nbsp;的,甚至是硕士,开始往测开赛道卷,说实话有点看不懂。先把话说清楚,大厂里的测开,绝大多数时间干的还是测试的活,只是写点自动化脚本、维护测试平台、接接流水线,真正像开发一样做系统、做架构、做核心平台的测开少得可怜,基本都集中在核心提效组,而且人很少,外面进去的大概率轮不到你,我想真正干过人都清楚。很多人被洗脑了,以为测开也是开,和后端差不多,只是更简单、更轻松、还高薪。现实情况是,测开和开发的职业路径完全不一样。开发的核心是业务和系统能力,测开的核心是稳定性和覆盖率,前者是往上走,后者天花板非常明显。你可以见到很多开发转测开,但你很少见到干了几年测开还能顺利转回开发的。更现实一点说,92&nbsp;的高学历如果拿来做测开,大部分时间就是在做重复性很强的杂活,这种工作对个人能力的放大效应非常弱。三年下来,你和一个双非的,甚至本科的测开差距不会太大,但你和同龄的后端、平台开发差距会非常明显。这不是努不努力的问题,是赛道问题。所谓测开简单高薪,本质上是把极少数核心测开的上限,当成了整个岗位的常态来宣传。那些工资高、技术强的测开,本身就是开发水平,只是挂了个测开的名。普通人进去,99%&nbsp;做的都是项目兜底型工作,而不是你想象中的平台开发。测开不是不能做,但它绝对不是开发的平替,也不是性价比最优解。如果你是真的不想做开发,追求稳定,那测开没问题。但如果你只是觉得测开比后端容易,还能进大厂,那我劝你冷静一点,这只是在用短期安全感换长期天花板。有92的学历,如果你连测开这些重复性工作都能心甘情愿接受,那你把时间精力用在真正的开发、系统、业务深度上,回报大概率比卷测开要高得多。想清楚再下场,别被岗位名和话术带偏了,就算去个前端客户端也是随便占坑的,测开是一个坑位很少赛道,反而大面积学历下放,不用想也能知道会是什么结果,我想各位在JAVA那里已经看到了
小浪_Coding:工作只是谋生的手段 而不是相互比较和歧视
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务