一、集合
提供以下可直接使用的User类,直接使用getter/setter方法。
编写测试类主函数,模拟创建5个用户,分属3个不同城市。
创建Set集合,添加以上元素对象。
import java.util.Set;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
class User {
private int id;
private String name;
private String city;
public User(int id, String name, String city) {
this.id = id;
this.name = name;
this.city = city;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public void show() {//输出信息
System.out.printf("id:%d name:%s city:%s\n",getId(),getName(),getCity());
}
}
public class Main {
public static void main(String[] args) {
User u1=new User(1,"Jack","Harbin");
User u2=new User(2,"Alice","Shanghai");
User u3=new User(3,"Bob","Shanghai");
User u4=new User(4,"Mike","Harbin");
User u5=new User(5,"John","Beijing");
Set<User> s=new HashSet<>();
s.add(u1);s.add(u2);s.add(u3);s.add(u4);s.add(u5);
//use function code...
}
//static function code...
}
(1) forEach方法,遍历Set/List/Map:
Set<User> set=new HashSet<>();
set.forEach(u->u.show());
List<User> list=new ArrayList<>();
list.forEach(u->u.show());
Map<String,Set<User>> map=new HashMap<>();
map.forEach((key,value)->{
//函数
});
(2) Set转List: 创建静态方法,传入封装User类型元素的Set集合,转为List集合返回。
private static List<User> setToList(Set<User>set) {
List<User> list = new ArrayList<>(set);
return list;
}
(3) 迭代器删除: 创建静态方法,传入封装User类型元素的Set集合,以及用户ID,基于迭代器,在集合移除指定ID用户。
private static void remove(Set<User> users, int id) {
Iterator<User> userIterator = users.iterator();
while (userIterator.hasNext()) {
User u = userIterator.next();
if (id == u.getId()) userIterator.remove();
}
}
(4) Set转Map分组: 创建静态方法,传入封装User类型元素的Set集合,将集合中元素,以城市名称为键,相同城市用户集合为值,分组。
private static void toMap(Set<User> users) {
Map<String, Set<User>> map = new HashMap<>();
for (User u : users) {
Set<User> set = map.getOrDefault(u.getCity(), new HashSet<>());
//若map.get(u.getCity())为空则返回new HashSet<>(),否则返回u.getCity()
set.add(u);
map.put(u.getCity(), set);
/*方法2
Set<User> set = map.get(u.getCity());
if (set == null) map.put(u.getCity(), new HashSet<>());
set.add(u);*/
}
}
二、集合流 stream
提供以下可直接使用的Student类,在Main.class中,按需求编写方法,完成对STUDENTS集合的操作。
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Comparator;
import java.util.stream.Collectors;
class Student {
private int number;
private String name;
private String clazz;
private int score;
public Student(int number, String name, String clazz, int score) {
this.number = number;
this.name = name;
this.clazz = clazz;
this.score = score;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
public class StreamTest {
private static final List<Student> STUDENTS = create();
private static final String CLAZZ1 = "软件1班";
private static final String CLAZZ2 = "软件2班";
private static List<Student> create() {
Student s1 = new Student(2018008, "张扬", CLAZZ2, 66);
Student s2 = new Student(2018005, "刘飞", CLAZZ1, 92);
Student s3 = new Student(2018007, "李明", CLAZZ2, 42);
Student s4 = new Student(2018006, "赵勇", CLAZZ2, 56);
Student s5 = new Student(2018002, "王磊", CLAZZ1, 81);
Student s6 = new Student(2018010, "牛娜", CLAZZ1, 78);
List<Student> students = new ArrayList<>();
students.add(s1);students.add(s2);students.add(s3);
students.add(s4);students.add(s5);students.add(s6);
return students;
}
public static void main(String[] args) {
// 调用实现方法测试
}
// 实现方法
}
(1) 使用stream() 获得集合流,filter() 过滤,map() 映射为新的类型,sort() 排序,collect() 聚合为集合。
获取指定班级,成绩小于等于指定分数,成绩由高到低排序的,全部学生的姓名。返回姓名的List集合。
private static List<String> lessThanScore3(String clazz,int score){//返回符合条件的姓名
return STUDENTS.stream()
.filter(s->clazz.equals(s.getClazz()))
.filter(s->s.getScore()<=score)
.sorted(Comparator.comparing(Student::getScore).reversed()) //不加reversed()就是默认升序
.map(s->s.getName()) //或者 .map(Student::getName)
.collect(Collectors.toList());
}
(2) Collectors.toMap(),分组。(按需求也可使用Collectors.groupingBy())
以学生学号为键,学生分数为值,Map分组,返回。
private static Map<Integer,Integer> group(String clazz,int score){
return STUDENTS.stream()
.collect(Collectors.toMap(Student::getNumber,Student::getScore));
}
三、Optional容器
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
class Teacher {
private String name;
public Teacher(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Course {
private String name;
private boolean elective;//选修课为ture
private Teacher teacher;
public Course(String name, boolean elective, Teacher teacher) {
this.name = name;
this.elective = elective;
this.teacher = teacher;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isElective() {
return elective;
}
public void setElective(boolean elective) {
this.elective = elective;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
public class Main {
public static void main(String[] args) {
// 调用实现方法测试
}
// 实现方法
}
(1) 基于指定课程,打印课程名称。
Optional<T> Optional.ofNullable(T value)
基于可能为空的对象,创建optional容器。
void ifPresent(action)
当optional容器不为空时,执行指定函数,为空则忽略执行。
public class Main {
public static void main(String[] args) {
Course c1 = new Course("Java程序设计",true,new Teacher("老师A"));
Course c2 = new Course(null,true,null);//没有课程和老师实例
Course c3 = new Course("计算机组成原理",false,new Teacher("老师B"));
Course c4 = new Course(null,false,new Teacher(null));//没有课程和老师名字(有老师实例)
List<Course> Courses = new ArrayList<>();
Courses.add(c1);Courses.add(c2);
Courses.add(c3);Courses.add(c4);
Courses.forEach(c->printName(c));//遍历输出course名字
}
public static void printName(Course course) {//对于每个course,打印它的名字,如果名字不存在就打印null
Optional.ofNullable(course)
.ifPresent(c->System.out.println(c.getName()));
}
}
输出:
Java程序设计
null
计算机组成原理
null
(2) 基于给定课程,如果课程不是选修课,返回课程的名称。任何不符合条件,返回“课程不存在”。
T orElse(T other)
当前容器不为空则返回容器中元素,为空则返回括号内的默认值。返回的不再是Optional容器,而是容器中最终的元素对象。无论是否为空,均创建默认对象。
filter(),map()用法同stream。
public class Main {
public static void main(String[] args) {
Course c1 = new Course("Java程序设计",true,new Teacher("老师A"));
Course c2 = new Course(null,true,null);//没有课程和老师实例
Course c3 = new Course("计算机组成原理",false,new Teacher("老师B"));
Course c4 = new Course(null,false,new Teacher(null));//没有课程和老师名字(有老师实例)
List<Course> Courses = new ArrayList<>();
Courses.add(c1);Courses.add(c2);
Courses.add(c3);Courses.add(c4);
Courses.forEach(c->System.out.println(notElective(c)));//遍历输出有名字的课且是非选修课
}
public static String notElective(Course course) {
//对于每个course,判断是否为选修,如果不是选修就返回名字,其他均返回"课程不存在"
return Optional.ofNullable(course)
.filter(c->!c.isElective())
.map(c->c.getName())
.orElse("课程不存在");
}
}
输出:
课程不存在
课程不存在
计算机组成原理
课程不存在
(3) 基于给定课程,如果课程是选修课,返回课程的授课教师的姓名。任何不符合条件,返回“教师未知”。
public class Main {
public static void main(String[] args) {
Course c1 = new Course("Java程序设计",true,new Teacher("老师A"));
Course c2 = new Course(null,true,null);//没有课程和老师实例
Course c3 = new Course("计算机组成原理",false,new Teacher("老师B"));
Course c4 = new Course(null,true,new Teacher(null));//没有课程和老师名字(有老师实例)
List<Course> Courses = new ArrayList<>();
Courses.add(c1);Courses.add(c2);
Courses.add(c3);Courses.add(c4);
Courses.forEach(c->System.out.println(electiveTeacher(c)));//遍历输出选修课的教师姓名
}
public static String electiveTeacher(Course course) {
//对于每个course,判断是否为选修,如果是选修就返回教师姓名,其他均返回"教师未知"
return Optional.ofNullable(course)
.filter(c->c.isElective())
.map(c->c.getTeacher()) //.map(Course::getTeacher)
.map(t->t.getName()) //.map(Teacher::getName)
.orElse("教师未知");
}
}
输出:
老师A
教师未知
老师B
教师未知
UPD 2020.5.10 集合与集合流,补充:
(1) 如果是要以分数为键,学生集合为分组,即返回Map<Integer,List<Student>>
类型,
在集合流中使用.collect(Collectors.groupingBy(s->s.getScore))
(2) 删除指定学号queryNumber的学生,返回是否删除成功,
在集合中使用removeIf(s->s.getNumber==queryNumber)
Collectors.groupingBy(),removeIf()实例: