注解
注解:解释代码的代码
常用的注解:
@Override:重写
@Deprecated:过时
@SuppressWarnings("deprecation"):忽略警告
自定义注解
语法:
访问权限修饰符 @ interface 注解名{
公共静态常量
注解属性
}
1.注解的属性语法格式:
数据类型 属性名();
数据类型 属性名() default 默认值;
2.如果注解的属性没有默认值,使用注解时,必须给属性赋值
3.如果注解的属性有默认值,使用注解时,可以给该属性赋值,也可以使用默认值
4.注解属性的数据类型不能是集合
注解的使用
注解下面要有代码的,没代码会报错
@注解名(属性名1 = 属性值1,属性名2 =, 属性值2,属性名3 = {})
注意:
1,可以不按照顺序赋值
2,有默认值的属性可以不赋值
不按顺序写可以,有默认值的也可以直接写
3,如果注解中所有属性都有默认值或没有属性,此时可以省略()不写
4,如果注解中有且只有一个value属性,在使用注解时,可以忽略属性名不写
如:
@注解名(值);
元注解
概念:解释注解的注解
常用的元注解:
@Target:
作用:限定注解的使用范围
值:
TYPE:可以在类上用
FIELD:在属性上用
METHOD:在方法上用
PARAMETER:在形参上用
CONSTRUCTOR:在构造函数上用
ANNOTATION_TYPE:在定义注解时用
此时,此注解如果不在方法上使用就会报错
注意:自定义一个注解不使用此注解时,可在任意位置使用
@Retention
作用:限制器使用范围(在什么情况下使用)
值:
SOURCE:在java文件时可用
CLASS:编译为class文件可用
RUNTIME:程序运行时可用
注意:
自定义的注解默认是java文件时可用
@Documented
作用:可以生成api文件
@Inherited
作用:允许被继承
注意:不加是不被继承的
注解+反射
比如想改一个类的默认值
import java.lang.reflect.Constructor;
import java.util.Arrays;
public class Cat {
private String name;
private int age;
private String color;
private String[] likeFood;
public Cat(String name, int age, String color, String[] likeFood) {
super();
this.name = name;
this.age = age;
this.color = color;
this.likeFood = likeFood;
}
@CatAnnotation(name = "小花",color = "花",age = 2)
public Cat() throws NoSuchMethodException, SecurityException {
super();
Class<Cat> c = Cat.class;//获取类对象
Constructor<Cat> con = c.getDeclaredConstructor();//获取无参构造函数
CatAnnotation annotation = con.getAnnotation(CatAnnotation.class);//获取注解传入
this.name = annotation.name();//获取注解中的属性值,并赋值给对应的属性
this.age = annotation.age();
this.color = annotation.color();
this.likeFood = annotation.likeFood();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String[] getLikeFood() {
return likeFood;
}
public void setLikeFood(String[] likeFood) {
this.likeFood = likeFood;
}
@Override
public String toString() {
return "猫 名字" + name + ", 年龄:" + age + ", 颜色:" + color + ", 喜欢的食物=" + Arrays.toString(likeFood)
+ "\n";
}
}
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.CONSTRUCTOR)
public @interface CatAnnotation {
String name() default "猫";
int age() default 1;
String color() default "黑";
String[] likeFood() default {"老鼠","鱼"};
}
public class Test {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Cat cat = new Cat();
System.out.println(cat);
}
}
Jdk1.8新特性
函数式接口
简介:一个接口只有一个抽象方法,但是可以有多个非抽象方法。这种接口称为函数式接口
注解:@FunctionalInterface,作用验证接口是否为函数式接口
系统提供的常见函数式接口
接口名 | 返回值类型 | 抽象方法 | 分类 |
Consumer<t> | void | accept(T t) | 消费型接口 |
Supplier<T> | T | get() | 供给型接口 |
Function<T,R> | R | apply(T t) | 函数型接口 |
Predicate<T> | boolean | test(T t) | 断言型接口 |
Lambda
简介:一种特殊的匿名内部类
优点:语法简洁,节省内存,不会生成class文件
缺点:太过简洁,对于新手来说可读性差
语法
TreeSet<String> set = new TreeSet<String>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return 0;
}
});
1,创建匿名内部类中只有一个方法,此时才能使用Lambda表达式
TreeSet<String> set = new TreeSet<String>((String o1, String o2) -> {
return 0;
});
2,在Lambda表达式中,可以省略形参的数据类型
TreeSet<String> set = new TreeSet<String>((o1, o2) -> {
return o1.compareTo(o2);
});
3,在Lambda表达式中,当只有一个形参时可以忽略小括号不写
4,当代码块中只有一行代码时,可以省略大括号不写
public class Test03 {
public static void main(String[] args) {
MyInter inter = new MyInter() {
@Override
public void tese(int num) {
System.out.println("你好世界");
}
};//匿名内部类
MyInter inter2 = (int num) ->{
System.out.println("你好世界");
};// Lambda表答式
MyInter inter3 = ( num) ->{
System.out.println("你好世界");
};//可以省略参数类型
MyInter inter4 = num -> {
System.out.println("你好世界");
};//只有一个参数时省略小括号
MyInter inter5 = num -> System.out.println("你好世界");//只有一行代码时省略大括号
}
}
interface MyInter{
void tese(int num);
}
5,当代码块中只有一行代码,此代码块为返回值,此时如果需要省略大括号,也要将return去掉
MyInter02 inter02 = ()->0;
interface MyInter02{
int tese();
}
例子:
/**
* 定义一个方法传入字符串,返回字符串长度
* 使用函数式接口
* Function
*/
// Function<String, Integer> function = new Function<String, Integer>() {
// @Override
// public Integer apply(String t) {
//
// return t.length();
// }
// };
Function<String, Integer> function = t->t.length();
Integer len = function.apply("红岸基地");
System.out.println(len);
方法引用
简介:在Lambda表达式前提下的一些特殊情况可继续做简化
常见形式:
对象::实例方法
package test4;
public class Per {
private String name;
public Per() {
super();
}
public Per(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Per [name=" + name + "]";
}
public void name() {
System.out.println(name);
}
}
//Consumer<Per> con1 = t->t.name();//形参传入的内容就是方法体中所使用的对象
Consumer<Per> con1 = Per::name;
con1.accept(per);
类::静态方法
// Consumer<Integer> con2 = new Consumer<Integer>() {
//
// @Override
// public void accept(Integer t) {
// Utils.output(t);
// }
// };
//
//
//Consumer<Integer> con2 = t->Utils.output(t);
Consumer<Integer> con2 = Utils::output;
//当传入的形参与方法中代码的实参一致,就可以使用方法引用
con2.accept(9527);
class Utils{
public void out(Integer t) {
System.out.println(t);
}
public static void output(Integer t) {
System.out.println(t);
}
}
类::实例方法
Utils tils = new Utils();
Consumer<Integer> con1 = new Consumer<Integer>() {
@Override
public void accept(Integer t) {
tils.out(t);
}
};
//Consumer<Integer>con1 = t->tils.out(t);
//当传入的参数就是方法中代码的实参,可以使用方法引用
Consumer<Integer>con1 = tils::out;
con1.accept(45);
class Utils{
public void out(Integer t) {
System.out.println(t);
}
}
类::new
顺序要一致
// Supplier<Per> sup = new Supplier<Per>() {
// @Override
// public Per get() {
//
// return new Per();
// }
// };
// Supplier<Per> sup = ()->new Per();
// //当方法体中没有形参列表,而且方法体中只有一行代码,而且该代码用于创建对象
// // 可以使用方法引用简写
Supplier<Per> sup = Per::new;
Per per = sup.get(); //调用就会提供Per对象
// Function<String, Per> fun = new Function<String, Per>() {
//
// @Override
// public Per apply(String t) {
//
// return new Per(t);
// }
// };
// Function<String, Per> fun = t->new Per(t);
Function<String, Per> fun =Per::new ;
fun.apply("庄颜");
流
简介
Stream:工作流
类似集合,区别是集合中存的是数据,流中存的是过程
特点:自己不会存储数据,不会改变源对象,也可以延迟执行
使用步骤
1.创建
2.中间操作
中间键可以有多个
3.终止操作
一旦进行终止操作,流就不能·在使用了
(链条式开发:上一个方法的返回值是下一个方法的调用的对象)
创建
方式1:
通过Collection对象的stream方法获取 串行流 按数据的顺序一个一个来
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0,1,2,3,4,5,6,7,8,9);
Stream<Integer> stream = list.stream();//按数据的顺序一个一个来
// stream.forEach(new Consumer<Integer>() {
// @Override
// public void accept(Integer t) {
// System.out.print(t);
// }
// });
// stream.forEach(t->System.out.print(t));
stream.forEach(System.out::print);
通过Collection对象的parallelStream方法获取 并行流 不管顺序
System.out.println();
System.out.println("-------------------");
Stream<Integer> stream2 = list.parallelStream();//不管顺序
// stream2.forEach(new Consumer<Integer>() {
// @Override
// public void accept(Integer t) {
// System.out.print(t);
// }
// });
// stream2.forEach(t->System.out.print(t));
stream2.forEach(System.out::print);
方式2:
通过Arrays提供的stream方法
int[] nums = {0,1,2,3,4,5,6,7,8,9};
IntStream stream3 = Arrays.stream(nums);
// stream3.forEach(t->System.out.print(t));
stream3.forEach(System.out::print);
方式3:
通过Stream接口提供的of,iterate,generate
代码:of普通流
//Stream<Integer> stream = Stream.of(0,1,2,3,4,5,6,7,8,9);
// Stream.of(0,1,2,3,4,5,6,7,8,9).forEach(t->System.out.println(t));
Stream.of(0,1,2,3,4,5,6,7,8,9).forEach(System.out::print);
代码:iterate迭代流
代码:generate生成流
方式4:
通过Stream接口子类或子接口对象调用of,iterate,generate
中间操作
filter:过滤
limit:限制
skip:跳过
distinct去掉重复
sorted排序
map映射操作
parallel并行流
注意:一个流可以有多个中间操作,也可以没有
1,filter过滤
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
//获取薪资大于15000,forEach终止操作,遍历结果
list.stream()
.filter(e->e.getMoney()>15000)
.forEach(System.out::println);
2,limit限制
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
//获取集合中前两个输出
list.stream()
.limit(2)
.forEach(System.out::println);
3,skip跳过
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
//跳过集合中前两个输出
list.stream()
.skip(2)
.forEach(System.out::println);
4,distinct去掉重复
注意:存储对象必须实现hashCode()和equals()方法,用这两个方法判断是否重复,先调用哪个hashCode方法,如果该方法的返回值与存储其他数据一致,在调用equals比较
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
list.stream()
.distinct()
.forEach(System.out::println);
5,sorted排序
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
list.stream()
.sorted((e1,e2)->Double.compare(e1.getMoney(), e2.getMoney()))
.forEach(System.out::println);
6,map映射操作
简介:将当前Stream中的每个元素都映射转换为另一个元素,从而得到一个新的Stream
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
list.stream()
.map(e->e.getName())
.forEach(System.out::println);
7,parallel并行流
简介:采用多线程 效率高
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
list.stream().parallel()
.forEach(System.out::println);
结束操作
forEach遍历
min最小值
max最大值
count数量
reduce规约
collect收集
注意:一个流有且只有一个结束操作
1,forEach遍历
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
list.stream().forEach(System.out::println);
2,min最小值
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
Optional<Employee> min = list.stream().min((o1,o2)->Integer.compare(o1.getMoney(), o2.getMoney()));
System.out.println(min.get());
3,max最大值
代码:
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
Optional<Employee> max = list.stream().max((e1,e2)->Integer.compare(e1.getMoney(), e2.getMoney()));
System.out.println(max.get());
4,count数量
代码:
//薪资大于20000的人数
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
long count = list.stream().filter(o -> o.getMoney()>20000).count();
System.out.println(count);
5,reduce规约
代码:
//所有员工薪资和
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
Optional<Double> sum = list.stream()
.map(e->e.getMoney())
.reduce((x,y)->x+y);
System.out.println(sum.get());
6,collect收集
代码:
//获取所有的员工姓名,封装成一个list集合
ArrayList<Employee> list=new ArrayList<>();
list.add(new Employee("小王", 15000));
list.add(new Employee("小张", 12000));
list.add(new Employee("小李", 18000));
list.add(new Employee("小孙", 20000));
list.add(new Employee("小刘", 25000));
list.add(new Employee("小刘", 25000));
List<String> names = list.stream()
.map(e->e.getName())
.collect(Collectors.toList());
for (String string : names) {
System.out.println(string);
}
文章评论