一、Stream流
1、定义
jdk8.0 出现的新类型,专门处理 数组/集合中的数据 【数据源】,可以将Stream当作管道,对数据源进行一系列【过滤 映射 截取 跳过收等】操作,简化代码。
用Stream流的时候,不能以中间方式结束语句,必须以终端方法介绍语句。
2、中间方法
filter((x)->boolean) 过滤流中符合条件的元素 组成新流返回
limit(x) 截取流中前x个元素组成新流返回
skip(x) 舍弃前x个元素,将剩余元素组成新流返回
distinct() 去重 - 去除重复元素 【底层 hashCode()+equals()】
map((T)->R) 将这个函数应用到流中的每一个元素身上[不影响个数]
sorted() 按照流中元素的类型的自然顺序进行排序
sorted((x,old)->int) 按照比较器的定制顺序进行排序
3、终端方法
void
forEach((x)->void) 遍历流中每一个元素进行统一操作
boolean
anyMatch((x)->boolean) 至少一个匹配上条件 - true
allMatch((x)->boolean) 全部匹配条件 - true
noneMath((x)->boolean) 全部不匹配条件 - true
Optional
findFirst() 返回流中第一个元素
max((x,old)->int) 返回最大的元素 [最后一个元素+升序]
min((x,old)->int) 返回最小的元素[第一个+升序]
reduce((sum,x)->sum+x) 合并归约 [求和] 【sum x sum+x 三者类型一致!】
long
count() 返回流中元素的个数
List/Set/Map/String
List<T> collect(Collectors.toList())
Set<T> collect(Collectors.toSet())
collect(Collectors.toMap(主键,值))
collect(Collectors.toMap(主键,值,(oldV,newV)->oldV))
4、处理对象
1 Stream ss = 单值集合对象.stream();
2 Stream ss = Arrays.stream(引用数据类型的数组);
3 Stream ss = Stream.of(T ... x);
5、代码示例
import java.util.*;
import java.util.stream.*;
public class Exec1{
public static void main(String[] args){
ArrayList<Student> list = new ArrayList<>();
Student s1 = new Student("Lee",23, 100);
Student s2 = new Student("Andy",18, 90);
Student s3 = new Student("Anron",21, 99);
Student s4 = new Student("Andy",20, 90);
Collections.addAll(list,s1,s2,s3,s4);
// 打印前2个A开头的学生
//list.stream().map(x ->x.getName()).filter(x -> x.startsWith("A")).limit(2).forEach(x -> System.out.println(x));
//list.stream().map(x ->x.getScore()).sorted((x,old) -> old - x).forEach(x -> System.out.println(x));
//list.stream().sorted().forEach(x -> System.out.println(x.getScore()));
//list.stream().filter(x -> x.getName().startsWith("A")).limit(2).forEach(x -> System.out.println(x));
// 1 A开头 filter
// 2 前两个 limit
//list.stream().distinct().forEach(x -> System.out.println(x));
// 3 forEach
//Stream<Student>
/**
System.out.println(list.stream()
.anyMatch(x -> x.getName().startsWith("A")));
System.out.println((list.stream()
.filter(x -> x.getScore() == 90)
.map(Student::getName)
.findFirst())
.orElse("")
);
System.out.println((list.stream()
.filter(x -> x.getScore() == 90)
.findFirst())
//.orElse(new Student("",0,0))
.orElseGet(Student :: new)
);
System.out.println(list.stream()
.max((x,y) -> x.getAge() - y.getAge())
.map(Student::getName)
.orElse(""));
System.out.println(list.stream()
.max((x,y) -> y.getName().length() - x.getName().length())
.map(Student::getName)
.orElse(""));
System.out.println(list.stream()
.map(Student::getName)
.filter(x -> x.startsWith("A"))
.count());
System.out.println(list.stream()
.map(Student::getScore)
.reduce((sum,x) -> sum + x)
.orElse(0));
List<Student> list_1 = list.stream()
.filter(x -> x.getAge() > 20)
.collect(Collectors.toList());
System.out.println(list_1);
List<String> list_2 = list.stream()
.map(Student::getName)
.collect(Collectors.toList());
System.out.println(list_2);
*/
Map<String,Integer> map = list.stream()
.collect(Collectors.toMap(Student::getName,Student::getAge,(x,y) -> x));
System.out.println(map);
}
}
class Student implements Comparable<Student>{
private String name;
private int age;
private int score;
public Student(){}
public Student(String name,int age, int score){
this.name = name;
this.age = age;
this.score = score;
}
public String toString(){
return name +":"+age+":"+score;
}
public int compareTo(Student x){
if(this.score != x.getScore())return x.getScore() - this.score;
return 1; //代表相同的对象也会被保留,如果相同的对象不需要保留,那么return 0;
}
public boolean equals(Object obj){
Student x = (Student) obj;
if(this == obj)return true;
if(this.name.equals(x.getName()) && this.age == x.getAge() && this.score == x.getScore())return true;
return false;
}
public int hashCode(){
return score + name.hashCode() + age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public int getScore(){
return this.score;
}
public void setScore(){
this.score = score;
}
}
该段代码、功能处全面注释掉了,每一块需要使用时取消注释使用,功能都是分开实现的。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.*;
// 晚上练习
public class ExecTonight1{
public static void main(String[] args) {
List<Person> list = new ArrayList<Person>();
list.add(new Person("Tom", 8900, '男', "New York",45));
list.add(new Person("Jack", 7000, '男', "Washington",52));
list.add(new Person("Lily", 7800, '女', "Washington",38));
list.add(new Person("Anni", 8200, '女', "New York",27));
list.add(new Person("Owen", 9500, '男', "New York",55));
list.add(new Person("Alisa", 7900, '女', "New York",40));
list.add(new Person("Jack", 7000, '男', "Washington",52));
/**
//按照男女分组
List<Person> list_G = list.stream()
.filter(x -> x.getSex()=='女')
.collect(Collectors.toList());
List<Person> list_B = list.stream()
.filter(x -> x.getSex()=='男')
.collect(Collectors.toList());
System.out.println(list_G);
System.out.println(list_B);
Map<Character,List<Person>>map = list.stream()
.collect(Collectors.groupingBy(x -> x.getSex()));
System.out.println(map);
//将全部员工工资上涨1000
list.stream()
.forEach(x -> x.setSalary(x.getSalary() + 1000));
System.out.println(list);
//打印所有工资>8000的员工信息
list.stream()
.filter(x -> x.getSalary() > 8000)
.forEach(x -> System.out.println(x));
//打印所有工资>8000的前两位信息
list.stream()
.filter(x -> x.getSalary() > 8000)
.limit(2)
.forEach(x -> System.out.println(x));
//按照工资降序
list = list.stream()
.sorted((x,y) -> y.getSalary() - x.getSalary())
.collect(Collectors.toList());
System.out.println(list);
//筛选工资>8000 装在List集合
list = list.stream()
.filter(x -> x.getSalary() > 8000)【
.collect(Collectors.toList());
System.out.println(list);
//将所有年龄>=40岁的员工 将姓名放在新集合Set里面
Set<String> set = list.stream()
.filter(x -> x.getAge() >= 40)
.map(x -> x.getName())
.collect(Collectors.toSet());
System.out.println(set);
//求所有人的工资之和
int sum1 = list.stream()
.map(x -> x.getSalary())
.reduce((sum,x)-> sum + x)
.orElse(0);
System.out.println(sum1);
//多少个>平均工资的
int avg =sum1 / list.size();
System.out.println(avg);
System.out.println+list.stream()
.filter(x -> x.getSalary() >= avg)
.count());
//谁是最高工资的那个员工
System.out.println(list.stream()
.max((x,old)->x.getSalary()-old.getSalary())
.map(x -> x.getName())
.orElse(""));
//得到最高的工资
System.out.println(list.stream()
.max((x,old)->x.getSalary()-old.getSalary())
.map(x -> x.getSalary())
.orElse(0));
//所有年龄>=45岁 工资8000以上的删除
list = list.stream()
.filter(x -> x.getAge() < 45)
.filter(x -> x.getSalary() < 8000)
.collect(Collectors.toList());
System.out.println(list);
//将所有工资8000以上的员工姓名和年龄统计在map集合里面
Map<String,Integer>map = list.stream()
.filter(x -> x.getSalary() > 8000)
.collect(Collectors.toMap(Person::getName,Person::getAge));
System.out.println(map);
//名字里面最长的员工
String name = null;
System.out.println(list.stream()
.max((x,old)->x.getName().length()-old.getName().length())
.map(x -> x.getName())
.orElse(""));
//打印集合里面第一个女生信息
list.stream()
.filter(x -> x.getSex() == '女')
.limit(1)
.forEach(x -> System.out.println(x));
*/
}
}
class Person {
private String name; // 姓名
private int salary; // 薪资
private int age; // 年龄
private char sex; //性别
private String area; // 地区
public Person(){}
// 构造方法
public Person(String name, int salary, char sex,String area,int age) {
this.name = name;
this.salary = salary;
this.sex = sex;
this.area = area;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
@Override
public String toString() {
return name + ":" + age +":" + salary+ ":" + sex + ":" + area;
}
}
这是我两个不熟练使用的方法,特别贴出来让我记忆一下
import java.util.*;
import java.util.stream.*;
public class Exec1{
public static void main(String[] args){
String str = "张三,李四,王五,张三,李四";
List<String> list = new ArrayList<>();
String ax[] = str.split(",");
//统计每个名字出现的次数
Map<String,Integer> map = Arrays.stream(ax)
.collect(Collectors.toMap(x -> x, x -> 1 ,(a,b)->a+1));//主键存x_name,值存1,如果已经存在该主键,则执行第三个
System.out.print(map);
Map<String,List<String>> map1 = Arrays.stream(ax)
.collect(Collectors.groupingBy(x -> x));//第二个X是分组依据,前面是操作的对象
System.out.print(map1);
}
}
二、枚举
1、定义
- 特点:如果一个类型只能创建确定个数的对象,该类型可以变为枚举类型
- 场景:Season - 4个季节/月份 - 12/星期 - 7/红绿灯 - 3
已经继承自Object类因此有默认的以下方法 toString() equals() hashCode() => Object
2、涉及的方法
1 将枚举类型所有的枚举常量收集到 【数组】
枚举类型[] data = 枚举类型.values();
2 将枚举类型所有的枚举常量收集到 【集合】【EnumSet - 单值集合】
EnumSet<枚举类型> set = EnumSet.allOf(枚举类型.class);
3 枚举类型 => String [获取某一个枚举常量的名字]
String name = 枚举常量.name();
4 String => 枚举类型[名字=>某一个枚举常量]
枚举类型 ss = 枚举类型.valueOf(String内容);
必须确保String内容是某一个枚举常量的名字 否则运行异常 - 非法参数异常
5 获取某一个枚举常量的序数【下标】
int index = 枚举常量.ordinal();
6 compareTo
枚举常量1.compareTo(枚举常量2);
枚举常量1.ordinal() - 枚举常量2.ordinal();
7 toString()/equals()/hashCode()
toString() - 任何一个枚举类型可以方法覆盖
equals()/hashCode() 再Enum中已经添加了final
所以任何一个枚举类型都无法进行覆盖【逻辑跟Object一样】
3、代码示例
import java.util.*;
import java.util.stream.*;
public class Exec3{
public static void main(String[] args){
// 1 展示所有的部门
show();
}
public static void show(){
Scanner sc = new Scanner(System.in);
Dept[] data = Dept.values();
EnumSet<Dept>set = EnumSet.allOf(Dept.class);
for(Dept x : data){System.out.println(x);
}
System.out.println("请选择入职的部门:");
// 接收用户的输入
String dept = sc.next();
//枚举类型 ss = 枚举类型.valueOf(String内容);
boolean flag = set.stream()
.anyMatch(x -> dept.equals(x.name()));
System.out.print(flag? "成功入职" : "入职失败");
}
}
enum Dept{
市场部{public String toString(){return "市场部";}},
教学部{public String toString(){return "教学部";}},
行政部{public String toString(){return "行政部";}},
就业部{public String toString(){return "就业部";}};
}
import java.util.*;
public class Exec4{
public static void main(String[] args){
EnumSet<Type>set = EnumSet.allOf(Type.class);
set.stream()
.forEach(x -> {System.out.println(x);});
System.out.println("请选择要挂号的科目");
Scanner sc = new Scanner(System.in);
// 只要用户输入的不存在 就一直重新输入
// while
a:while(true){
String in = sc.next();
if(set.stream().anyMatch(x -> in.equals(x.name())))break a;
System.out.println("重输");
}
System.out.println("挂号成功");
}
}
enum Type{
清热解毒,肠胃不适,咽喉疼痛,其他;
}