Java 集合 集合流 Optional容器 (练习题,用法总结)

一、集合

提供以下可直接使用的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()实例:在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ljw_study_in_CSDN/article/details/105826155