【第二十五天】JDK8部分特性:接口可以实体方法、Lambda表达式、函数式接口、Stream、时间包

复习:

1. 反射:剖析一个类,分析这个类的字节码,获取对应的字节码对象以及产生对应的实例对象的过程。

 

 

--- 获取字节码对象:

类名.class,对象.getClass(),

Class.forName(类的全路径名)

利用字节码对象获取实例对象

 

 

---clz.newInstance(),要求这个类中必须有无参构造

获取类中对应形式的构造方法对象,

然后利用Constructor对象来产生对应的实例对象。

 

--- 利用反射实现解耦操作

 

2. 单元测试:导入Junit测试库,@Test,@Before,@After --- 要求使用的方法没有参数,没有返回值,是非静态的。

 

3. 注解:本质上是一个接口。利用@interface来定义一个注解。注解中的属性在定义的时候类型只能是基本类型、String、Class、其他注解类型、枚举类型以及这五个类型的一维数组形式。

元注解:@Target,@Retention,@Documented,@Inherited

 

 

JDK8的部分特性

接口中的默认方法

从jdk1.8开始,接口中允许定义实体方法。然而这个非静态方法必须用default修饰,而且这个方法必须用public修饰。接口中也允许定义静态方法。

多实现,多继承

interface A {

public default int m(){

return 0;

}

}

interface B {

public default String m(){

return null;

}

}

class C implements A, B {}

C c = new C();

int ? String?c.m();

 

 1 package cn.sgy.day180210;
 2 
 3 public class InterfaceMethodDemo {
 4 
 5     public static void main(String[] args) {
 6         
 7         Calculator c = new Calculator() {
 8 
 9             @Override
10             public int add(int i, int j) {
11                 return i+j;
12             }
13             
14         };
15         
16         System.out.println(c.max(4, 9));
17     }
18 }
19 
20 interface Calculator{
21     
22     
23     public int add (int i, int j);
24     
25     public default int max (int i, int j) {
26         return i>j ? i:j;
27     }
28     
29     
30     public static double sqrt(double d) {
31         return Math.sqrt(d);
32     }
33 }

 

Lambda表达式

利用指定的表达式形式来重写接口中的抽象方法

(参数列表) -> {方法体}

不产生内部类,任何一个Lambda表达式都不能直接赋值给Object

注意:当利用Lambda表达式来重写方法的时候,要求这个接口中只能有一个抽象方法

 

 

 

函数式接口

Comparator   ,    FileFilter   ,    FilenameFilter

接口中只含有一个抽象方法的接口---函数式接口---@FunctionalInterface(新注解)

Predicate---仲裁者---判断参数是否符合指定的规则

package cn.sgy.day180210;

import java.util.function.Predicate;

public class PredictDemo {

    
    public static void main(String[] args) {
        
        
        Predicate<String> p = str -> str.startsWith("a");
        
        System.out.println(p.test("abc"));
        System.out.println("kfc".startsWith("a"));
    }
}

 

Function---转化者---按照指定规则将参数转化为结果类型

package cn.sgy.day180210;

import java.util.function.Function;

public class FunctionDemo {

    public static void main(String[] args) {
    
        
        Function<String, Double> f = str -> Math.sqrt(Double.parseDouble(str));
        
        System.out.println(f.apply("2.25"));
        
        Function<String, Boolean> f2 = f.andThen(d -> d >10);
        
        System.out.println(f2.apply("4.8"));
    }
}

 

 

Supplier---供给者---不需要参数,会返回一个值

package cn.sgy.day180210;

import java.util.function.Supplier;

public class SupplierDemo {

    public static void main(String[] args) {
        
        
        Supplier<Double> s = Math::random;
        
        System.out.println(s.get());
    }
}

 

 

Consumer --- 消费者---需要参数但是没有返回值

package cn.sgy.day180210;

import java.util.function.Consumer;

public class ConsumerDemo {

    
    public static void main(String[] args) {
        
        
//        Consumer<String> c = str -> System.out.println(str);
        Consumer<String> c = System.out :: println;
        
        c.accept("abc");
    }
}

 

 

 

Stream

不是函数式接口不是流,而是不存储数据的流式结构。---提供了大量的方法允许对数据进行批量操作:排序,过滤,映射,规约等方法。根据方法的返回值类型分为中间方法(返回值类型依然是Stream)和完结方法(返回值类型是其他类型)。

 1 package cn.tedu.stream;
 2 
 3 import java.util.Arrays;
 4 import java.util.List;
 5 import java.util.Optional;
 6 import java.util.stream.Stream;
 7 
 8 public class StreamDemo1 {
 9 
10 public static void main(String[] args) {
11 
12 List<String> list = Arrays.asList("Mike", "Grace", "Jack", "Bob", "John", "Alex", "Selina");
13 
14 // 获取Stream
15 Stream<String> stream = list.stream();
16 
17 // 筛选列表中J开头的名字-> 将所有字母转化为大写
18 // stream.filter(str -> str.startsWith("J")).map(str ->
19 // str.toUpperCase()).forEach(System.out::println);
20 
21 // 筛选含有'a'的字符串---获取筛选之后的个数
22 // System.out.println(stream.filter(str -> str.contains("a")).count());
23 
24 // 判断集合中是否含有出现'm'的字符串
25 // System.out.println(stream.filter(str -> str.contains("m")).count() >
26 // 0);
27 // System.out.println(stream.anyMatch(str -> str.contains("a")));
28 
29 // 判断集合中的所有字符串是否都是由字母组成的
30 //    System.out.println(stream.filter(str ->
31 //    str.matches("[a-zA-Z]+")).count() == list.size());
32 //    System.out.println(stream.allMatch(str -> str.matches("[a-zA-Z]+")));
33 
34 Optional<String> o = stream.reduce((str1, str2) -> str1 + "~" + str2);
35 System.out.println(o);
36 }
37 
38 }
39 
40  
41 
42 运行时候一次只能运行一个输出  多个输出会报错

 

 

规约---利用指定规则计算元素之间的关系(不是简单的合并还需要去重合)

 

Optional<String> o = stram.reduce((str1,str2) -> str1 + "~" +str2);

 

(Optional为了防止产生空集合对象)

 

 

 

时间包

jdk8中对时间体系进行了全新的划分,划分出来一个代表时间的包---java.time

LocalDate---只含有日期而不含有时间
LocalTime---只含有时间而不含有日期

 

旧的方法 Date

 

package cn.sgy.day180210;

import java.util.Date;


public class TimeDemo {

    
    public static void main(String[] args) {
        
        Date data = new  Date();
        
        System.out.println(data);
    }
}

 

 

毫秒 --- millis

微秒 --- micros

纳秒 --- nanos

 

Time包

package cn.tede.time;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

//import java.util.Date;

public class LocalDateDemo {

    public static void main(String[] args) {

        // Date date = new Date();
        // System.out.println(date);

        // 一个只含有日期而不含有时间的类
        // 表示获取当前系统的日期
        // LocalDate date = LocalDate.now();
        // System.out.println(date);

        // 指定日期
        LocalDate date = LocalDate.of(2018, 3, 1);
        System.out.println(date);

        System.out.println(date.getDayOfMonth());
        System.out.println(date.getDayOfWeek());
        System.out.println(date.getDayOfYear());

        // 判断是否是一个闰年
        System.out.println(date.isLeapYear());

        System.out.println(date.plus(5, ChronoUnit.MILLENNIA));
        // System.out.println(date.minus(3,ChronoUnit.MILLENNIA));
    }

}

 

 

 

 

JVM的运行参数问题

栈内存---计算---每个线程私有一个栈

堆内存---存储对象---被所有线程所共享的

方法区---存储类信息和常量---被所有线程所共享的

本地方法栈---计算---每个线程私有一个本地方法栈

pc计数器---计数和计算线程执行的指令---每个线程所私有的

-Xss:用于限制栈内存的大小的 -Xss128K表示当前线程的栈内存为128K 

-Xmn 设置新生代大小

-Xms 设置堆内存的初始内存大小

-Xmx 设置堆内存的最大可用大小

例如: -Xss128k -Xmn5M -Xms10M -Xmx10M表示每个线程的大小是128k,新生代5M,可用堆内存10M,最大可用内存为10M

java -Xmn5M -Xms7M -Xmx10M -XX:+PrintGCDetails Demo

 

 

标准参数:-cp

非标准参数:-Xmn -Xss

扩展参数:-XX:+PrintGC -XX:+PrintGCDetails 打印我的回收细节

{解释:GC初代回收(回收新生代,,括号里面是整个内存的大小)第一行结束发现还是放不开,内存变大是因为一些变量又被初始化了,第二次回收以后依然放不开,于是试着往老生代里面放,老生代回收以后还是放不开来这时候就再回收,最后一行就是老生代新生代一起回收,但是还是放不开于是会报错}

eden space 伊甸园区80%---4M

from space和to space 是两块幸存区 各占10%合起来是20%

伊甸园区和幸存区比例是4:1

ParOldGen老生代  7M大小

PSPermGen持久代 Metaspace方法区

 

 

 

 

GC的回收机制

Mark-sweeping---标记-清理   会出现内存碎片化

Copying---复制---内存耗费会比较大

 

 

 

Mark-compact---标记-整理---比较充分的利用内存,内存耗费小

 

 

posted @ 2018-02-09 10:48  songyao  阅读(190)  评论(0编辑  收藏  举报