概述
为何有不可变集合
如何创建
public class Test {
public static void main(String[] args) {
//1.不可变List集合
List<Double> scores = List.of(457.0,703.5,570.0,403.5);
//scores.add(200.5);报错
//scores.set(1,500.0);报错
System.out.println(scores);
System.out.println(scores.get(1));
//2.不可变Set集合
Set<String> names = Set.of("马浩楠", "程明辉", "李泽", "吴赛");
//names.add("马儿扎哈");报错
//names.remove("李泽");报错
System.out.println(names);
//3.不可变Map集合
Map<String, Integer> commodity = Map.of("舒肤佳", 2, "手表", 3, "JavaSe", 1);
//commodity.put("HTML",1);报错
System.out.println(commodity);
}
}
目的:用于简化集合和数组操作的API
Stream流思想核心:
public class Test {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
Collections.addAll(names,"张三丰","张无忌","赵敏","光明左使","张三");
System.out.println(names);
//1.从集合中找出姓张的放到新集合
/*ArrayList<String> zhangList = new ArrayList<>();
for (String name : names) {
if(name.startsWith("张")){
zhangList.add(name);
}
}
System.out.println(zhangList);*/
//2.找出名字长度为3姓张的名字放到新集合
/*ArrayList<String> zhangThreel = new ArrayList<>();
for (String s : zhangList) {
if(s.length() == 3){
zhangThreel.add(s);
}
}
System.out.println(zhangThreel);*/
//3.使用stream实现
names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
}
}
public class Test {
public static void main(String[] args) {
//1.Collection集合获取Stream流
List<String> list = new ArrayList<>();
Stream<String> listStream = list.stream();
//2.Map集合获取Stream流
Map<String,Integer> maps = new HashMap<>();
//键流
Stream<String> keyStream = maps.keySet().stream();
//值流
Stream<Integer> valueStream = maps.values().stream();
//键值流
Stream<Map.Entry<String, Integer>> keyAndValueStream = maps.entrySet().stream();
//3.数组获取Stream流
String[] names = {"马浩楠", "程明辉", "李泽", "吴赛"};
Stream<String> arrStream = Arrays.stream(names);
Stream<String> arrStream1 = Stream.of(names);
}
}
【注意】:
【Stream流常见终结操作方法】
终结操作方法,调用完成后流就无法继续使用了,原因是不会返回Stream了
public class Test {
public static void main(String[] args) {
//1.forEach:遍历
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张三丰","张无忌","赵敏","光明左使","张三","张三丰");
list.stream().forEach(s -> System.out.println(s));
//2.统计个数
System.out.println("元素个数:"+list.stream().count());
//3.过滤元素(取姓张的元素)
list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));
//4.取前几个元素
System.out.println("-------------取前几个---------------");
list.stream().limit(2).forEach(s -> System.out.println(s));
//5.跳过前几个元素
System.out.println("-------------跳过前几个--------------");
list.stream().skip(3).forEach(s -> System.out.println(s));
//6.加工
System.out.println("加工后:");
list.stream().map(s -> "洛阳理工的"+s).forEach(s -> System.out.println(s));
//加工成对象
list.stream().map(s -> new Student(s)).forEach(s -> System.out.println(s));
//7.合并流
Stream<String> s1 = list.stream().filter(s -> s.startsWith("张"));
Stream<String> s2 = Stream.of("Java", "HTML");
Stream.concat(s1,s2).forEach(s -> System.out.println(s));
}
}
【案例】:某公司的开发部门,分为一部开发和二部开发,现在需要进行年中数据结算
统计两个开发部门整体的平均工资,去掉最高和最低工资
Employee
public class Employee {
private String name;
private char sex;
private double salary;
private double prize;
private String punish;
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", sex=" + sex +
", salary=" + salary +
", prize=" + prize +
", punish='" + punish + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public double getPrize() {
return prize;
}
public void setPrize(double prize) {
this.prize = prize;
}
public String getPunish() {
return punish;
}
public void setPunish(String punish) {
this.punish = punish;
}
public Employee(String name, char sex, double salary, double prize, String punish) {
this.name = name;
this.sex = sex;
this.salary = salary;
this.prize = prize;
this.punish = punish;
}
public Employee() {
}
}
public class Topperformer {
private String name;
private double salary;
private double prize;
@Override
public String toString() {
return "Topperformer{" +
"name='" + name + '\'' +
", salary=" + salary +
", prize=" + prize +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public double getPrize() {
return prize;
}
public void setPrize(double prize) {
this.prize = prize;
}
public Topperformer(String name, double salary, double prize) {
this.name = name;
this.salary = salary;
this.prize = prize;
}
public Topperformer() {
}
}
public class Test {
//部门1 去掉最高和最低工资
public static double oneAllMoney;
//部门2 去掉最高和最低工资
public static double twoAllMoney;
//两个部门平均月收入
public static double allMoney;
public static void main(String[] args) {
List<Employee> one = new ArrayList<>();
one.add(new Employee("猪八戒",'男',30000.0,25000.0,null));
one.add(new Employee("孙悟空",'男',25000.0,1000.0,"顶撞上司"));
one.add(new Employee("沙僧",'男',20000.0,20000.0,null));
one.add(new Employee("小白龙",'男',20000.0,25000.0,null));
List<Employee> two = new ArrayList<>();
two.add(new Employee("武松",'男',15000,9000.0,null));
two.add(new Employee("李逵",'男',20000,10000.0,null));
two.add(new Employee("西门庆",'男',50000.0,100000.0,"被打"));
two.add(new Employee("潘金莲",'女',3500.0,1000.0,"被打"));
two.add(new Employee("武大郎",'男',20000.0,0.0,"下毒"));
//分别筛选出2个部门最高工资的员工信息,封装成优秀员工对象Topperformer
Topperformer t = perfectEmployee(one);
System.out.println("部门一优秀员工:"+t);
Topperformer t2 = perfectEmployee(two);
System.out.println("部门二优秀员工:"+t2);
//分别统计出2个部门的平均月收入,去掉最高和最低工资
System.out.println("部门一平均收入(去掉最高和最低):"+averageIncome(one));
System.out.println("部门二平均收入(去掉最高和最低):"+averageIncome(two));
//统计2个开发部门整体的平均工资,去掉最低和最高工资的平均值
Stream<Employee> s1 = one.stream();
Stream<Employee> s2 = two.stream();
Stream.concat(s1,s2).sorted((o1,o2) -> Double.compare(o1.getSalary()+o1.getPrize(),o2.getSalary()+o2.getPrize()))
.skip(1).limit(one.size()+two.size() - 2).forEach(s ->{
allMoney += s.getSalary()+s.getPrize();
});
BigDecimal big1 = BigDecimal.valueOf(allMoney);
BigDecimal big2 = BigDecimal.valueOf(one.size() + two.size() - 2);
//精度失真问题,使用BigDecimal,(RoundingMode.HALF_UP:四舍五入)
System.out.println("两个部门一起的平均收入为:"+big1.divide(big2,2, RoundingMode.HALF_UP));
}
//分别筛选出2个部门最高工资的员工信息,封装成优秀员工对象Topperformer
public static Topperformer perfectEmployee(List<Employee> list){
return list.stream().max((o1, o2) -> Double.compare(o1.getSalary() + o1.getPrize(), o2.getSalary() + o2.getPrize()))
.map(o -> new Topperformer(o.getName(), o.getSalary(), o.getPrize())).get();
}
//分别统计出2个部门的平均月收入,去掉最高和最低工资
public static double averageIncome(List<Employee> list){
list.stream().sorted(((o1, o2) -> Double.compare((o1.getSalary()+o1.getPrize()),(o2.getSalary()+o2.getPrize()))))
.skip(1).limit(list.size() - 2).forEach(s -> {
oneAllMoney += (s.getPrize()+s.getSalary());
});
return oneAllMoney / (list.size() -2);
}
}
public class Test {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
Collections.addAll(names,"张三丰","张无忌","赵敏","光明左使","张三");
//1.流转为List集合
Stream<String> s1 = names.stream().filter(s -> s.startsWith("张"));
//List<String> list = s1.collect(Collectors.toList());
//当前版本存在了新的API
List<String> list = s1.toList();//但这个获取的List是不可变集合
System.out.println(list);
//2.转为Set集合 【注意:流只能使用一次,所以需要再次拿到Stream)
Stream<String> s2 = names.stream().filter(s -> s.startsWith("张"));
Set<String> set = s2.collect(Collectors.toSet());
System.out.println(set);
//3.转为数组
Stream<String> s3 = names.stream().filter(s -> s.startsWith("张"));
Object[] arr = s3.toArray();
System.out.println(Arrays.toString(arr));
}
}
public class Test {
public static void main(String[] args) {
//1.数组索引越界异常:ArrayIndexOutOfBoundsException
int[] arr = {26,33,99};
System.out.println(arr[1]);
//System.out.println(arr[3]);运行报错,程序终止
//2.空指针异常:NullPointerExcpetion
String name = null;
System.out.println(name);
//System.out.println(name.length());运行报错,程序终止
//3.类型转换异常:ClassCastExcpetion
Object s = 23;
//String str = (String) s;运行报错,程序终止
//4.数学操作异常:ArithmeticException
//int a = 3/0;
//5.数字转换异常:NumberFormatExcpetion
String number = "50aaa";
//Integer num = Integer.valueOf(number);运行报错,程序终止
}
}
String date = "2001-03-02 10:23:21";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(date);//出现编译时异常
System.out.println(d);
【编译时异常是编译阶段就出现错误的,必须处理,否则代码无法编译运行】
public class Test {
public static void main(String[] args) throws Exception{
String birthDay = "2001-03-02 11:12:13";
Date date = formatDate(birthDay);
System.out.println(date);
}
public static Date formatDate(String str) throws Exception{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(str);
return date;
}
}
public class Test {
public static void main(String[] args) throws Exception{
String birthDay = "2001-03-02 11:12:13";
Date date = formatDate(birthDay);
System.out.println(date);
}
public static Date formatDate(String str){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = sdf.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
public class Test {
public static void main(String[] args){
String birthDay = "2001-03-02 11:12:13";
Date date = null;
try {
date = formatDate(birthDay);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(date);
}
public static Date formatDate(String str) throws Exception{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(str);
return date;
}
}
【需求】
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
try {
while(true){
System.out.println("请输入定价:");
String priceStr = input.nextLine();
Double price = Double.valueOf(priceStr);
if(price > 0){
System.out.println("定价为:"+price);
break;
}
System.out.println("定价必须为正数,请重新输入");
}
} catch (NumberFormatException e) {
System.out.println("输入有误,请重新输入,建议为正数!");
}
}
}
好处
自定义编译时异常
【AgeIllegalException自定义编译时异常】
public class AgeIllegalException extends Exception{
public AgeIllegalException() {
}
public AgeIllegalException(String message) {
super(message);
}
}
【Test】
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入年龄:");
try {
checkAge(Integer.valueOf(input.nextInt()));
} catch (AgeIllegalException e) {
e.printStackTrace();
}
}
public static void checkAge(Integer age) throws AgeIllegalException {
if(age<0 || age>200){
throw new AgeIllegalException(age+"is illegal!");
}else {
System.out.println("年龄合法!");
}
}
}
【AgeIllegalRuntimeException自定义运行异常】
public class AgeIllegalRunTimeException extends RuntimeException{
public AgeIllegalRunTimeException() {
}
public AgeIllegalRunTimeException(String message) {
super(message);
}
}
【Test】
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入年龄:");
checkAge(Integer.valueOf(input.nextInt()));//不会编译报错,但建议外层依然进行 try catch
}
public static void checkAge(Integer age) {
if(age<0 || age>200){
throw new AgeIllegalRunTimeException(age+"is illegal!");
}else {
System.out.println("年龄合法!");
}
}
}