一个图书管理的例子
现有一批图书的信息,图书管理员需要对目前的图书做一个大致的了解,需要从不同维度进行统计
序号 | 书名 | 发行时间 | 类别 | 楼层 | 价格 |
---|---|---|---|---|---|
1 | 红楼梦 | 1994-01-02 | 文学 | 1 | 20.80 |
2 | java编程思想 | 1999-11-02 | 技术 | 2 | 50.40 |
3 | 史记 | 2001-11-02 | 历史 | 3 | 32 |
4 | 圣经 | 1979-11-02 | 外国文学 | 2 | 15.5 |
5 | 高等数学 | 2008-11-02 | 教材 | 5 | 15 |
6 | 单片机 | 2009-11-02 | 教材 | 5 | 11.5 |
… | … | … | … | … |
于是我们拷贝了整个excel的数据,直接拿原始文本进行处理.
1.定义图书实体类
static class Book{
//主题
String category;
//发布时间
Date publishDate;
//书名
String name;
//价格
Double price;
Book(){}
Book(String category, Date publishDate,String name,Double price){
this.category = category;
this.publishDate = publishDate;
this.name = name;
this.price = price;
}
}
2.将文本转换成结构化数据
public void createBookList() {
//从Excel中直接复制出来的格式
String excelData = "1\t红楼梦\t1994-01-02\t文学\t1\t20.80\n" +
"2\tjava编程思想\t1999-11-02\t技术\t2\t50.40\n" +
"3\t史记\t2001-11-02\t历史\t3\t32\n" +
"4\t圣经\t1979-11-02\t外国文学\t2\t15.5\n" +
"5\t高等数学\t2008-11-02\t教材\t5\t15\n" +
"6\t单片机\t2009-11-02\t教材\t5\t11.5";
//使用Pattern.splitAsStream(),将字符串分割成流
Pattern pattern = Pattern.compile("\\n");
Stream<String> stringStream = pattern.splitAsStream(excelData);
//或使用以下方式获取每一行的数据
//Stream<String> stringStream = new BufferedReader(new StringReader(excelData)).lines();
books = stringStream.map(x->{
String[] cols = x.split("\\t");
String category = cols[3];
String name = cols[1];
Double price = Double.parseDouble(cols[5]);
Date publishDate = null;
try {
publishDate = new SimpleDateFormat("yyyy-MM-dd").parse(cols[2]);
} catch (ParseException e) {
e.printStackTrace();
}
return new Book(category,publishDate,name,price);
}).collect(Collectors.toList());
}
3.统计图书信息
public void stream(){
//逐行打印出所有书名
books.stream().map(Book::getName).forEach(System.out::println);
//红楼梦
//java编程思想
//史记
//圣经
//高等数学
//单片机
//peek 不会中断流
List<Book> newBooks = books.stream().peek(x->x.setPrice(100*x.getPrice())).sorted(Comparator.comparingDouble(Book::getPrice)).collect(Collectors.toList());
//foreach 会中断流操作
books.stream().forEach(x->x.setPrice(100*x.getPrice()));
//将书名用书名号”《》“分割打印
String bookNames = books.stream().map(Book::getName).collect(Collectors.joining("》《","《","》")).toString();
// 《红楼梦》《java编程思想》《史记》《圣经》《高等数学》《单片机》
//获得对图书价格的统计信息
DoubleSummaryStatistics summaryStatistics = books.stream().collect(Collectors.summarizingDouble(Book::getPrice));
double sumPrice = summaryStatistics.getSum(); //145.2
//求出所有图书平均价格
double averagePrice = summaryStatistics.getAverage(); // 24.2
//求出所有图书最低价格
double minPrice = summaryStatistics.getMin(); // 24.2
//求出所有图书最高价格
double maxPrice = summaryStatistics.getMax(); // 24.2
//统计各类别的图书对应的总价
Map<String,Double> categorySumMap = books.stream()
.collect(Collectors.groupingBy(Book::getCategory,Collectors.summingDouble(Book::getPrice)));
//技术->50.4,文学->20.8,外国文学->15.5,历史->32.0,教材->26.5
//根据类别统计图书平均价格
Map<String,Double> categoryAverageMap = books.stream()
.collect(Collectors.groupingBy(Book::getCategory,Collectors.collectingAndThen(Collectors.summarizingDouble(Book::getPrice),x->x.getAverage())));
//技术->50.4,文学->20.8,外国文学->15.5,历史->32.0,教材->13.25
//按发布时间排序
List<Book> sortedBookList = books.stream().sorted((x1,x2)->{
return x1.getPublishDate().after(x2.getPublishDate())?1:-1;
}).collect(Collectors.toList());
//将图书分成教材书和非教材书
Map<Boolean,List<Book>> booleanListMap = books.stream().collect(Collectors.partitioningBy(x->"教材".equals(x.getCategory())));
}
使用Stream生成数据和分页
public void iterate(){
// 迭代器,从0开始,新的元素 = 上一个元素 + 2 , 共迭代六次结束
List<Integer> list = Stream.iterate(0,x -> x+2).limit(6).collect(Collectors.toList());
list.stream(); // 0 2 4 6 8 10
//跳过前n个,(n=2)
list.stream().skip(2); // 4 6 8 10
//只取前n个
list.stream().limit(2); // 0 2
//skip 和 limit 可以用来做分页
// pageSize = 2 , 取第4页数据时,可以
int pageSize = 2; int pageNum = 4 ;
Stream.iterate(1,x->x+1).limit(100).skip((pageNum-1) * pageSize).limit(pageSize).forEach(System.out::println);
// 7 , 8
// 生成随机数
Stream.generate(Math::random).limit(4).forEach(System.out::println); //生成4个小于1的随机数
new Random().ints(10).forEach(System.out::println);//生成10个整形数
new Random().ints(10,0,10).forEach(System.out::println); //生成10个整形数,大小在0-10之间
}