Java8 Stream流式常见操作处理一道机试题

地铁里刷CSDN论坛的技术区看到一博客《记一道机试题》,当时大概记了一下题目,不是特别清晰,题目内容大致如下:

/**
 * 1 输出每个人的名字及其平均成绩
 * 2 以平均成绩的逆序排序
 * 3 要有良好的代码注释
 * 4 体现出Java面向对象的特性和代码复用性
 *
 * 输出结果(记得原题好像都是整数计算结果也是整数,因为要求平均成绩,根据实用性定义了double类型)
 * 李四 95.5
 * 王五 88.0
 * 张三 86.0
 */
public class Jh {
    public static void main(String[] args) {
        List<String> strList = Arrays.asList("1,张三,85","2,李四,91","3,王五,88","4,张三,86","5,李四,100","6,张三,87");
    }
}

参考代码

为了体现出Java面向对象的特性,首先建立学生(Student)对象,并重写toString方法:

package com.aiwen.test;

public class Student{
	/**
	 * 学生序号
	 */
	private String id;
	/**
	 * 学生姓名
	 */
	private String name;
	/**
	 * 学生分数
	 */
	private Double score;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Double getScore() {
		return score;
	}
	public void setScore(Double score) {
		this.score = score;
	}
	@Override
	public String toString() { //重写toString方法,以便对象直接输出
		return name + " " + score;
	}

为了代码易读性和复用性进行了方法的抽取,具体代码实现如下:

package com.aiwen.test;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 1 输出每个人的名字及其平均成绩
 * 2 以平均成绩的逆序排序
 * 3 要有良好的代码注释
 * 4 体现出Java面向对象的特性和代码复用性
 *
 * 输出结果(记得原题好像都是整数计算结果也是整数,因为要求平均成绩,根据实用性定义了double类型)
 * 李四 95.5
 * 王五 88.0
 * 张三 86.0
 */
public class Jh {
    public static void main(String[] args) {
        List<String> strList = Arrays.asList("1,张三,85","2,李四,91","3,王五,88","4,张三,86","5,李四,100","6,张三,87");
    
		strList.stream()//转换为字符串流Stream<String>
			.map(info->{//字符串流转换为Student对象流Stream<Student>
				return stringToStudent(info);
			}).collect(Collectors.groupingBy(Student::getName,Collectors.toList()))//分组进行收集    Map<String,List<Student>
			.entrySet().stream()//转换为Entry流Stream<Entry<String, List<Student>>> 
			.map(obj->{//装换为Student流Stream<Student>
				Student student = new Student();
				
				String studentName = obj.getKey();//获取分租姓名信息
				List<Student> studentList = obj.getValue(); //获取分组集合信息
				
				student.setName(studentName);//封装Name属性				
				student.setScore(getAverageScore(studentList));//封装Score属性<平均分>
				
				return student;
			}).sorted(Comparator.comparing(Student::getScore).reversed())//根据学生平均成绩逆序排序(由高到低)
			.forEach(System.out::println);//遍历输出学生信息(已重写toString()方法)		
		
	}
	
	/**
	 * 字符串转换为学生对象
	 * "1,张三,80.5" 转换为 new Student("1","张三",80.5)
	 * @param info
	 * @return Student
	 */
	private static Student stringToStudent(String info) {
		Student student = new Student();
		String[] split = info.split(",");//字符串切割
		//对象封装
		student.setId(split[0]);
		student.setName(split[1]);
		student.setScore(Double.valueOf(split[2]));	
		
		return student;
	}
	
	/**
	 * 获取学生集合信息获取平均成绩(四舍五入保留1位小数)
	 * @param list
	 * @return Double
	 */
	private static Double getAverageScore(List<Student> studentList) {
		Double average= studentList.stream()//转为Student对象流Stream<Student>
			.mapToDouble(Student::getScore)//根据分数转换为Double流Stream<Double>
			.average()//求平均值
			.orElse(0);	//如果值为空取值为0
		
		//四舍五入保留1位小数
		average = new BigDecimal(average).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
			
		return  average;
	}

}

运行结果

运行结果

关于Java8 stream 和 parallelStream 特殊用法待续

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值