java Stream流
Stream流的的方法:迭代与排序、映射(map)
/*
* 筛选切片
* filter
* limit
* skip
* distinct
* filter(Predicatep)接收Lambda ,从流中排除某些元素。
distinct()筛选,通过流所生成元素的hashCode() 和equals() 去除重复元素
limit(long maxSize)截断流,使其元素不超过给定数量。
skip(long n)跳过元素,返回一个扔掉了前n 个元素的流。若流中元素不足n 个,则返回一个空流。与limit(n) 互补
*/
List<Employee> emp=Arrays.asList(
new Employee(0, "zhangsan",18,9999.99),
new Employee(1,"lisi",20,999),
new Employee(2,"wangwu",25,999),
new Employee(3,"zhaoliu",20,8888)
);
//内部迭代:由Stream API完成
@Test
public void test1() {
//中间操作
Stream<Employee> s=emp.stream().filter((e)->{
System.out.println("123456");
return e.getAge()>35;
});
//终止操作:惰性求值
s.forEach(System.out::println);
}
@Test
public void test2() {
emp.stream()
.filter((e)-> {
System.out.println("短路");//&& || 短路与
return e.getAge()>35;
})
.limit(1)//找到满足的条件 1个 就停止
.forEach(System.out::println);
}
/*
* map(Functionf)接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
mapToDouble(ToDoubleFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的DoubleStream。
mapToInt(ToIntFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的IntStream。
mapToLong(ToLongFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的LongStream。
flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
*/
@Test
public void test5() {
List<String> list=Arrays.asList("aa","bb","cc","dd","ee");
list.stream()
.map((str) -> str.toUpperCase())
.forEach(System.out::println);
System.out.println("------------");
emp.stream()
.map(Employee::getName)
.forEach(System.out::println);
//将所有的流转为一个流{a,a,b,b,c,c}
Stream<Character> sm=list.stream()
.flatMap(TestStream2::filterCharacter);
sm.forEach(System.out::println);
}
public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for(Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
//排序
//自然排序sorted()
//定制排序sorted(Comparator com)
@Test
public void test7() {
List<String> list = Arrays.asList("ccc","bbb","aaa","ddd","ggg","eee");
list.stream()
.sorted()
.forEach(System.out::println);
System.out.println("----------------");
emp.stream()
.sorted((e1,e2) -> {
if(e1.getAge()==e2.getAge()) {
return e1.getName().compareTo(e2.getName());
}
return 0;
}).forEach(System.out::println);
}
Stream流的方法:查找与匹配、归约(reduece)、收集、求总和、求平均、最大、最小、分组、多级分组、分区、连接。
List<Employee> emps = Arrays.asList(
new Employee(0,"zhangsan",18,888.99,Status.FREE),
new Employee(1,"lisi",20,8888.99,Status.BUSY),
new Employee(2,"wangwu",18,8999.99,Status.VOCATION),
new Employee(3,"zhaoliu",25,8899.99,Status.FREE),
new Employee(4,"sunqi",34,10000.99,Status.FREE),
new Employee(3,"zhaoliu",26,8899.99,Status.FREE),
new Employee(4,"sunqi",55,10000.99,Status.FREE)
);
/*
* 查找与匹配
* allMatch --检查是否匹配所有的元素
* anyMatch --至少有一个匹配
* noneMatch --没有一个匹配
* findFirst --返回第一个元素
* count --元素个数
* max
* min
*
*/
@Test
public void test1() {
boolean b1 = emps.stream()
.allMatch((e) -> e.getStatus().equals(Status.BUSY));
System.out.println(b1);
boolean b2=emps.stream()
.anyMatch((e) -> e.getStatus().equals(Status.BUSY));
System.out.println(b2);
//排序,返回工资最低的
Optional<Employee> op=emps.stream()
.sorted((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary()))
.findFirst();
System.out.println(op.get());
//并行流,多线程执行
Optional<Employee> op2=emps.parallelStream()
.filter((e) -> e.getStatus().equals(Status.FREE))
.findAny();
System.out.println(op2.get());
}
@Test
public void test2() {
Long c1=emps.stream()
.count();
System.out.println(c1);
//返回工资最高的 人
Optional<Employee> op1=emps.stream()
.max((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary()));
System.out.println(op1.get());
//返回最小的工资
Optional<Double> op2=emps.stream()
.map(Employee::getSalary)
.min(Double::compare);
System.out.println(op2.get());
}
/*
* 归约
* reduce()
*
*/
@Test
public void test3() {
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
//将0作为x,取1作为y,x+y作为新的x,依次递归
Integer sum = list.stream()
.reduce(0,(x,y) -> x+y);
System.out.println(sum);
//总和可能为空,所以用optional 避免空指针异常
Optional<Double> op=emps.stream()
.map(Employee::getSalary)
.reduce(Double::sum);
System.out.println(op.get());
}
/*
* 收集:取出所有的名字,放入集合中,若有重复的放入set
* collect
*/
@Test
public void test4() {
List<String> list=emps.stream()
.map(Employee::getName)
.collect(Collectors.toList());
//遍历集合
list.forEach(System.out::println);
System.out.println("-----------------");
//放入set
Set<String> set=emps.stream()
.map(Employee::getName)
.collect(Collectors.toSet());
set.forEach(System.out::println);
System.out.println("=======================");
//特殊的集合中的
HashSet<String> hs=emps.stream()
.map(Employee::getName)
.collect(Collectors.toCollection(HashSet::new));
hs.forEach(System.out::println);;
}
@Test
public void test5() {
//求总人数
Long count = emps.stream()
.collect(Collectors.counting());
System.out.println("总数是:"+count);
//工资平均值
Double avg = emps.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println("工资的平均值:"+avg);
//工资的总和
Double sum = emps.stream()
.collect(Collectors.summingDouble(Employee::getSalary));
System.out.println("工资总和是:"+sum);
//最大值
Optional<Employee> ep1=emps.stream()
.collect(Collectors.maxBy((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary())));
System.out.println("工资最高的员工"+ep1.get());
//最小工资,先map映射到工资
Optional<Double> op2=emps.stream()
.map(Employee::getSalary)
.collect(Collectors.minBy(Double::compare));
System.out.println("工资最低是"+op2.get());
}
//分组
@Test
public void test6() {
Map<Status,List<Employee>> m1 = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus));
//System.out.println(m1);
}
//多级分组
@Test
public void test7() {
Map<Status,Map<String,List<Employee>>> map =emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus,Collectors.groupingBy((e) ->{
//指定e的类型
if(((Employee) e).getAge() <=35) {
return "青年";
}else if(((Employee) e).getAge() <=50) {
return "中年";
}else {
return "老年";
}
})));
System.out.println(map);
}
//分区:满足条件的一个区,不满足条件的一个区
@Test
public void test8() {
Map<Boolean,List<Employee>> map = emps.stream()
.collect(Collectors.partitioningBy((e) ->e.getSalary()>8000));
System.out.println(map);
}
// DoubleSummaryStatistics 可以获取总数,平均值,最大值最小值
@Test
public void test9() {
DoubleSummaryStatistics dss=emps.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(dss.getSum());
System.out.println(dss.getAverage());
System.out.println(dss.getCount());
}
//连接成字符串
@Test
public void test10() {
String str = emps.stream()
.map(Employee::getName)
.collect(Collectors.joining(","));
System.out.println(str.toString());
}
Stream Api
/**
*
* @author Mr.zhang
*
*/
public class TestStreamAPI1 {
//创建Stream
@Test
public void test1() {
//通过Collection
List<String> list = new ArrayList<>();
Stream<String> stream1=list.stream();
//通过Arrays中的静态方法Stream()
Employee[] emps= new Employee[10];
Stream<Employee> stream2 = Arrays.stream(emps);
//通过Stream中的静态方法of()
Stream<String> stream3 =Stream.of("aa","bb","cc");
//创建无限流
//迭代
Stream<Integer> stream4=Stream.iterate(0, (x)->x+2);
//stream4.limit(10).forEach(System.out::println);
//生成
Stream.generate(()->Math.random())
.limit(10).forEach(System.out::println);;
}
给定的数字列表,如何返回一个有每个数的平方构成的列表呢? 给定的【1,2,3,4,5】返回【1,4,9,16,25】
怎么样用map和reduce方法数一数流中有多少个Employee
/*
* 1:给定的数字列表,如何返回一个有每个数的平方构成的列表呢?
* 给定的【1,2,3,4,5】返回【1,4,9,16,25】
*/
@Test
public void test1() {
Integer[] nums = new Integer[] {1,2,3,4,5};
Arrays.stream(nums)
.map((x) -> x*x)
.forEach(System.out::println);
}
List<Employee> emps = Arrays.asList(
new Employee(0,"zhangsan",18,888.99,Status.FREE),
new Employee(1,"lisi",20,8888.99,Status.BUSY),
new Employee(2,"wangwu",18,8999.99,Status.VOCATION),
new Employee(3,"zhaoliu",25,8899.99,Status.FREE),
new Employee(4,"sunqi",34,10000.99,Status.FREE),
new Employee(3,"zhaoliu",26,8899.99,Status.FREE),
new Employee(4,"sunqi",55,10000.99,Status.FREE)
);
/*
* 2:怎么样用map和reduce方法数一数流中有多少个Employee
*
*/
@Test
public void test2() {
Optional<Integer> count = emps.stream()
.map((e) -> 1)
.reduce(Integer::sum);
System.out.println(count.get());
}
Fork_Join工作窃取模式
需要继承RecursiveTask
public class ForkJoin extends RecursiveTask<Long> {
/**Fork Join 模式
* 工作窃取
*/
private static final long serialVersionUID = 1L;
private long start;
private long end;
private static final long THRESHOLD =10000;
public ForkJoin(long start , long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long length = end - start;
long sum = 0;
if(length <= THRESHOLD) {
for(long i =start; i<= end; i++) {
sum+=i;
}
return sum;
}
else {
long middle =(start + end)/2;
ForkJoin left = new ForkJoin(start,middle);
left.fork();//拆分子任务,同时压入线程队列
ForkJoin right =new ForkJoin(middle+1,end);
right.fork();
return left.join() + right.join();
}
}
}
使用java8的并行流提高效率
public class TestForkJoin {
@Test
public void test1() {
/**
* java 8时间戳的使用
* Fork Join 框架
*/
Instant start = Instant.now();
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoin(0,10000000000L);
Long sum = pool.invoke(task);
System.out.println(sum);
Instant end = Instant.now();
//4109
System.out.println("耗费时间:"+Duration.between(start, end).toMillis());
}
@Test
public void test2() {
long sum = 0L;
Instant start = Instant.now();
for(long i =0;i <=10000000000L; i++) {
sum += i;
}
Instant end = Instant.now();
System.out.println(sum);
//3391
System.out.println("耗费时间:"+Duration.between(start, end).toMillis());
}
/*
* java8 并行流:parallel()
* 顺序流:sequential()
*
*/
@Test
public void test3() {
Instant start = Instant.now();
LongStream.rangeClosed(0, 10000000000L)
.parallel()
.reduce(0,Long::sum);
Instant end = Instant.now();
//2910
System.out.println("耗费时间:"+Duration.between(start, end).toMillis());
}
}
java8 Optional<>避免空指针异常
实体类省略setter getter
public class Godness {
private String name;
//省略.....
}
public class Man {
private Godness godness;
//省略。。。。
}
public class NewMan {
private Optional<Godness> godness = Optional.empty();
//省略。。。。
}
Optional 容器类:用于尽量避免空指针异常
/*
* 一、Optional 容器类:用于尽量避免空指针异常
* Optional.of(T t) : 创建一个 Optional 实例
* Optional.empty() : 创建一个空的 Optional 实例
* Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例
* isPresent() : 判断是否包含值
* orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
* orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
* map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
* flatMap(Function mapper):与 map 类似,要求返回值必须是Optional
*/
@Test
public void test1() {
Optional<Employee> op = Optional.of(new Employee());
//of() 里面不能是null
Employee emp = op.get();
System.out.println(emp);
}
@Test
public void test2() {
Optional<Employee> op = Optional.empty();
System.out.println(op.get());
}
@Test
public void test3() {
Optional<Employee> op = Optional.ofNullable(null);
/*if(op.isPresent()) {
System.out.println(op.get());
}*/
Employee emp = op.orElse(new Employee(1,"zhangsan",18,999.99,Status.BUSY));
System.out.println(emp);
}
@Test
public void test4() {
Optional<Employee> op = Optional.ofNullable(null);
Employee emp = op.orElseGet(() -> new Employee());
System.out.println(emp);
}
@Test
public void test5() {
Optional<Employee> op = Optional.ofNullable(new Employee(1,"zhangsan",18,999.99,Status.BUSY));
/*Optional<String> op2 = op.map((t) -> t.getName());
Optional<U> java.util.Optional.map(Function<? super T, ? extends U> mapper)
System.out.println(op2.get());*/
//Optional<U> java.util.Optional.flatMap(Function<? super T, Optional<U>> mapper)
//必须包装成Optional()
Optional<String> op3 = op.flatMap((e) -> Optional.of(e.getName()));
System.out.println(op3.get());
}
@Test
public void test6() {
Man man = new Man();
String s = getGodnessName(man);
System.out.println(s);
}
//需求:获取一个男人的女神的名字
public String getGodnessName(Man man) {
if(man != null) {
Godness gn = man.getGodness();
if(gn != null) {
return gn.getName();
}
}
return "苍老师";
}
public String getGodnessName2(Optional<NewMan> man) {
return man.orElse(new NewMan())
.getGodness()
.orElse(new Godness("苍老师"))
.getName();
}
@Test
public void test7() {
//ofNullable() 构建对象
// Optional<NewMan> op = Optional.ofNullable(null);
/* Optional<NewMan> op = Optional.ofNullable(new NewMan());
Optional<NewMan> op2 = Optional.ofNullable(null);*/
Optional<Godness> gn = Optional.ofNullable(new Godness("zhangsan"));
Optional<NewMan> op2 = Optional.ofNullable(new NewMan(gn));
String str = getGodnessName2(op2);
System.out.println(str);
}
java8 中允许接口中出现默认方法和静态方法
接口:
public interface MyFun {
/**
* java8 中允许接口中出现默认方法和静态方法
*
*/
default String getName() {
return "哈哈";
}
public static void show() {
System.out.println("接口中的静态方法");
}
}
public interface MyInterface {
default String getName() {
return "MyInterface";
}
}
public class SubClass /*extends TestMyclass*/ implements MyFun,MyInterface {
@Override
public String getName() {
// TODO Auto-generated method stub
return MyFun.super.getName();
}
/**
* SubClass extends TestMyclass implements MyFun,MyInterface
*
* SubClass 会实现 父类的同名方法
*/
}
public class TestMyclass {
public String getName() {
return "111222";
}
}
优先执行父类中的方法,当注释父类,就近执行接口同名方法
public class TestDefaultInterface {
public static void main(String[] args) {
SubClass sc = new SubClass();
System.out.println(sc.getName());
MyFun.show();
}
}
java8之前SimpleDateFormat 线程是不安全的
SimpleDateFormat 报错的解决方法
public class DateFormatThreadLoack {
private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
protected DateFormat initialValue() {
// SimpleDateFormat 线程单线程是不安全的 ,每次new 一个新的对象
return new SimpleDateFormat("yyyyMMdd");
}
};
public static Date covert(String source) throws ParseException {
return df.get().parse(source);
}
}
public class TestSimpleDateFormate {
/**
*
* @param args
* @throws Exception
* SimpleDateFormat 线程是不安全的
* 及解决方法 上锁
*
*/
public static void main(String[] args) throws Exception{
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
// TODO Auto-generated method stub
return DateFormatThreadLoack.covert("20171015");
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<Date>> results = new ArrayList<>();
for(int i = 0;i < 10; i++) {
results.add(pool.submit(task));
}
for(Future<Date> future : results) {
System.out.println(future.get());
}
pool.shutdown();
}
}
java8 时间的写法
public class TestNewDate {
/**
*
*java 8时间的使用
*
*/
public static void main(String[] args) throws Exception{
Callable<LocalDate> task = new Callable<LocalDate>() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
@Override
public LocalDate call() throws Exception {
return LocalDate.parse("20171015",dtf);
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> results = new ArrayList<>();
for(int i = 0;i < 10; i++) {
results.add(pool.submit(task));
}
for(Future<LocalDate> future : results) {
System.out.println(future.get());
}
pool.shutdown();
}
}
java 8本地时间,时间戳,时间校正器,时间格式化,时区处理
public class TestLocalDateTime {
//1 LocalDate LocalTime LocalDateTime
@Test
public void test1() {
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
LocalDateTime ldt2 = LocalDateTime.of(2017,12,12,10,9,8);
System.out.println(ldt2);
//ldt 加2年plusYears 减一个月 minusMoths(1)
LocalDateTime ldt3 = ldt.plusYears(2);
System.out.println(ldt3);
System.out.println("--------");
System.out.println(ldt.getYear());
System.out.println(ldt.getMonthValue());
System.out.println(ldt.getDayOfMonth());
System.out.println(ldt.getHour());
}
//Instant :时间戳
@Test
public void test2() {
Instant ins1 = Instant.now();//默认获取UTC时区
System.out.println(ins1);
OffsetDateTime odt = ins1.atOffset(ZoneOffset.ofHours(8));
System.out.println(odt);
//时间戳
System.out.println(ins1.toEpochMilli());
Instant ins2 = Instant.ofEpochSecond(60);
System.out.println(ins2);
}
//Duration :计算两个时间的间隔
//Period: 计算两个日期的间隔
@Test
public void test3() {
Instant ins1 = Instant.now();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Instant ins2 = Instant.now();
Duration duration = Duration.between(ins1, ins2);
/*
* 获取 s,ns:getSeconds() getNano()
* 获取ms :toMillis()
*/
System.out.println(duration.toMillis());
LocalTime ldt1 = LocalTime.now();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LocalTime ldt2 = LocalTime.now();
System.out.println(Duration.between(ldt1, ldt2).toMillis());
}
@Test
public void test5(){
LocalDate ld1 = LocalDate.of(2017, 1, 12);
LocalDate ld2 = LocalDate.now();
Period p = Period.between(ld1, ld2);
System.out.println(p);
System.out.println(p.getYears());
System.out.println(p.getMonths());
System.out.println(p.getDays());
}
/*
* 时间校正器 TemporalAdjuster
* TemporalAdjusters
*/
@Test
public void test6() {
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
LocalDateTime ldt2 = ldt.withDayOfMonth(10);
System.out.println(ldt2);
//下个周日是什么时间
LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(ldt3);
//自定义: 下一个工作日
LocalDateTime ldt5 = ldt.with((i) -> {
LocalDateTime ldt4 = (LocalDateTime)i;
DayOfWeek dow = ldt4.getDayOfWeek();
if(dow.equals(DayOfWeek.FRIDAY)) {
return ldt4.plusDays(3);
}else if(dow.equals(DayOfWeek.SATURDAY)) {
return ldt4.plusDays(2);
}else {
return ldt4.plusDays(1);
}
});
System.out.println(ldt5);
}
//格式化日期
@Test
public void test7() {
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE;
LocalDateTime ldt = LocalDateTime.now();
String str = ldt.format(dtf);
System.out.println(str);
System.out.println("-----------");
DateTimeFormatter dt2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
String str2 = dt2.format(ldt);
System.out.println(str2);
//格式化日期转换回ISO标准
LocalDateTime newDate = ldt.parse(str2, dt2);
System.out.println(newDate);
}
//带时区的时间
@Test
public void test8() {
Set<String> set = ZoneId .getAvailableZoneIds();
//遍历set
set.forEach(System.out::println);
}
@Test
public void test9() {
//其他时区此刻的时间
LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Europe/Monaco"));
System.out.println(ldt);
//带时区的此刻的当地时间
LocalDateTime ldt2 = LocalDateTime.now(ZoneId.of("Europe/Monaco"));
ZonedDateTime zdt = ldt2.atZone(ZoneId.of("Europe/Monaco"));
System.out.println(zdt);
}
}
重复注解与类型注解
/**
*
* @author Mr.zhang
* 去@SuppressWarnings找头文件
*/
@Repeatable(MyAnnotations.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE ,TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)//生命周期
public @interface MyAnnotation {
String value() default "com";
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
MyAnnotation[] value();
}
/**
* 重复注解与类型注解
* @author Mr.zhang
*
*/
public class TestAnnotation {
//配合框架使用 checker framework
private /*@NonNull*/ Object oj = null;
@MyAnnotation("Hello")
@MyAnnotation("World")
public void show(@MyAnnotation("abc") String str) {
}
//反射
@Test
public void test1() throws NoSuchMethodException, SecurityException {
Class<TestAnnotation> clazz = TestAnnotation.class;
Method m1 = clazz.getMethod("show");
MyAnnotation[] ma = m1.getAnnotationsByType(MyAnnotation.class);
for (MyAnnotation myAnnotation : ma) {
System.out.println(myAnnotation.value());
}
}
}