A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Mr摩羯座 初级黑马   /  2018-12-2 15:03  /  638 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

[石家庄校区]就业班,11-14day

UDP: User Datagram Protocol, 用户数据报协议
        特点:
                1. 无连接的不可靠协议
                2. 数据按包发送, 64K一个包
                3. 速度快效率高, 容易丢包
        用于视频直播, 网络电话
TCP: Transmission Control Protocol, 传输控制协议
        特点:
                1. 需要建立连接的可靠协议  电话
                2. 数据传输无大小限制
                3. 速度慢效率低   重发机制
        用于文件下载, 浏览网页

TCP通信的三次握手: TCP协议中, 在发送数据的准备阶段, 客户端与服务器之间的三次交互, 以保证连接的可

        1. 客户端向服务端发送验证信息, 等待服务器确认
        2. 服务端收到验证信息后, 回复客户端验证信息, 同时发送自己的一条验证信息
        3. 客户端收到服务端回复的信息, 确认自己之前发的信息无误, 并再次向服务器发回服务端的验证信息
java.net.ServerSocket类: TCP服务端
        // 构造方法
        ServerSocket(int port): 创建一个TCP服务端, 并监听指定端口
        // 成员方法
        Socket accept(): 监听数据, 会阻塞. 收到数据后返回Socket对象
        void close(): 关闭服务端ServerSocket

java.net.Socket类: TCP客户端
        // 构造方法
        Socket(String ip, int port): 创建TCP客户端对象
        // 成员方法
        OutputStream getOutputStream(): 获取输出流对象, 用于发送数据
        InputStream getInputStream(): 获取输入流, 用于接收数据
        void shutdownOutput(): 关闭输出流, 告知服务端数据发送完毕
        void close(): 关闭客户端Socket
Socket clientSocket = serverSocket.accept();
InetAddress inetAddress = clientSocket.getInetAddress();
String ip = inetAddress.getHostAddress();
String hostName = inetAddress.getHostName();

ava.util.function.Consumer<T>函数式接口: 消费型函数式接口
        // 抽象方法
        void accept(T  t): 用于消费(使用)一个对象或值. 至于怎么消费, 需要我们根据应用场景编写Lambda来实现
        // 默认方法
        default  Consumer<T>  andThen(Consumer<  super T>  after): 拼接两个Consumer接口的Lambda对象实现连续操作. 谁写前面, 谁先消费

java.util.function.Predicate<T>函数式接口: 条件接口, 用于判断
        // 抽象方法
        boolean?test(T  t): 判断参数传递的对象. 至于怎么判断, 要判断什么, 需要我们编写Lambda表达式来实现
        // 默认方法 (用于连接多个判断条件)
        default Predicate<T> and(Predicate<   super T> other): 与
        default Predicate<T> or(Predicate<  super T> other): 或
        default Predicate<T> negate(): 非, 取相反结果

java.util.function.Function<T,R>: 根据一个T类型的数据得到另一个R类型的数据
        T称为前置条件, 也就是输入(input)的类型
        R称为后置条件, 也就是返回结果(result)的类型
        有进有出, 所以称为"函数Function"
        // 抽象方法
        R?apply(T  t): 将T转换为R
        // 默认方法
        default <V> Function<T, V> andThen(Function<? super R, ? extends V> after): 拼接多个Function转换

函数式编程:        Stream流式思想:                 先编写所有处理方案, 最后再统一执行方案                应用场景: 简化对集合/数组复杂操作的代码                API        方法引用:                简化Lambda表达式, 直接引用一个已经存在的方法(成员方法, 静态方法, 构造方法)
Stream流式思想处理数据的方式:
        让代码的执行像流水线一样, 先设计好处理方案, 然后一按开关开始执行
       
流相比于集合的2个优点:
        1. Pipelining(管道特性): "可以链式调用"
                Stream流对象的 延迟方法 调用后, 会返回新的Stream流对象, 可以链式调用
                每个方法类似于一条一条的管道, 衔接了不同的处理方案
        2. 内部迭代特性: "不用写for循环"
                集合遍历通过 Iterator 或者 增强for, 显式的在集合外部进行迭代, 这叫做外部迭代
                Stream提供了内部迭代的方法 forEach(Consumer c), 可以直接调用遍历方法

使用Stream流的3个步骤:
        1. 获取数据源 (从"集合"或"数组"转换为"Stream"对象)
        2. 数据处理 (调用延迟方法, 编写处理方案)
        3. 获得结果 (调用终结方法, 启动开关)
延迟方法: (具有延迟执行的特性)
        返回值类型"是Stream"类型的方法, 支持链式调用
                Stream filter(): 过滤
                Stream map(): 映射/转换
                Stream limit(): 截取
                Stream skip(): 跳过
终结方法:
        返回值类型"不是Stream"类型的方法, 不支持链式调用
        void forEach(): 遍历
        long count(): 统计
       
注意:
        除了终结方法外, 其余方法均为延迟方法

           -------------------------------------------------
创建数据源-> filter()过滤 | map()映射 | limit()截取 | skip()跳过 -> forEach() | count()结果
           -------------------------------------------------  
  获取流                            转换                                  聚合
                                 (延迟方法)                            (终结方法)
new ArrayList().stream().filter(...).map(...).limit(...).skip(...).forEach(...);
Stream.of(1,2,3).filter(...).map(...).limit(...).skip(...).count();


java.util.stream.Stream<T>接口: 管道接口
        // 抽象方法
        void forEach(Consumer<? super T> action): 遍历流中的元素进行逐一消费. 并不保证元素的逐一消费动作在流中是被有序执行的
方法引用: Method Reference
        如果Lambda表达式仅仅是调用一个已经存在的方法, 那就可以通过方法引用来替代Lambda表达式
        作用: 简化Lambda表达式
        :: 方法引用运算符, 它所在的表达式被称为方法引用

Lambda表达式写法:
        (String s) -> System.out.println(s)   
    参数传递给System.out.println()方法去打印
方法引用写法:     
        System.out::println
        引用System.out.println()方法中代码, 来作为Lambda中重写方法的实现方式

注意:
        Lambda中, 重写方法的"参数", 必须是方法引用的方法"要接收的类型", 否则会抛出异常
        (String s) -> System.out.println(s)  方法有个参数String s
    System.out::println                  引用的println方法必须能接收String类型的s

方法引用能简化以下场景: (方法名后不要写小括号)
                场景                                                格式                          简化之前的Lambda                        方法引用简化后
        1. 通过对象名引用成员方法     对象名::成员方法名   ()->person.eat()          person::eat
        2. 通过类名引用静态方法       类名::静态方法名     i -> Math.abs(i)          Math::abs
        3. 通过super引用父类成员方法  super::父类方法名   ()->super.eat();          super::eat
        4. 通过this引用本类成员方法   this::本类方法名    ()->this.eat();           this::eat
        5. 引用某个类的构造方法       类名::new          name->new Person(name)    Person::new
        6. 引用创建数组的方法         数据类型[]::new    length->new int[length];  int[]::new
JUnit使用步骤:
        1. 定义一个测试类(也叫测试用例)
            包名:xxx.xxx.xx.test
                被测试的类名:   Calculator   
                对应的测试类名: CalculatorTest
        2. 定义测试方法:可以独立运行
                被测试的方法名:       add()      
        对应的测试方法名: testAdd()  
                    建议测试方法的返回值是void, 参数列表是空参
        3. 在方法上加 @Test 注解
        4. 在 @Test 注解上按 Alt+Enter, 选择 "Add 'JUnit4' to Classpath" 导入JUnit依赖环境
        5. 在方法名上右键, 选择 "Run '方法名()'"

判定结果:
        红色:失败
        绿色:成功.(测试通过)

断言: Assert
        使用断言操作来判断结果是否符合预期:

                Assert.assertEquals(期望的结果, 运算的结果);

                如果 期望的结果 和 运算的结果 相等, 则认为测试通过, 否则测试失败

测试失败的原因提示:
    java.lang.AssertionError:
    Expected :1    (表示我期望得到的是1)
    Actual   :-1   (但是实际得到的是-1)
Java代码在计算机中的3个阶段:
        SOURCE: 源代码阶段
        CLASS: 类对象阶段
        RUNTIME: 运行时阶段
获取一个类的字节码对象的3种方式:
        1. Class.forName("全类名")
        2. 类名.class                         .
        3. 对象.getClass()

java.lang.Class<T>类: 表示一个类的字节码对象, 其中包含该类中定义的内容
// 获取功能
// 1. 获取成员变量们
        Field[] getFields(): 获取所有 public 的成员变量
        Field getField(String name): 获取指定名称的 public 的成员变量
        Field[] getDeclaredFields(): 获取所有的成员变量, 不考虑权限修饰符
        Field getDeclaredField(String name): 获取指定名称的成员变量, 不考虑权限修饰符
// 2. 获取构造方法们
        Constructor<?>[] getConstructors(): 获取所有 public 的构造方法
        Constructor<T> getConstructor(Class<?>... parameterTypes): 获取指定的 public 构造方法
        Constructor<?>[] getDeclaredConstructors(): 获取所有的构造方法, 不考虑权限修饰符
        Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes): 获取指定的构造方法, 不考虑权限修饰符
// 3. 获取成员方法们:
        Method[] getMethods(): 获取所有 public 的成员方法
        Method getMethod(String name, Class<?>... parameterTypes) : 获取指定的 public 成员方法
        Method[] getDeclaredMethods(): 获取所有的成员方法, 不考虑权限修饰符
        Method getDeclaredMethod(String name, Class<?>... parameterTypes): 获取指定的成员方法, 不考虑权限修饰符
// 4. 获取Class对象代表的类的全类名
        String getName(): 获取当前Class对象代表的类的全类名
// 其他
        T newInstance(): 使用当前类的空参构造创建一个对象
        A getAnnotation(Class<A> annotationClass): 获取当前类的注解对象
        ClassLoader getClassLoader(): 返回该类的类加载器

java.lang.reflect.Field: 表示一个成员变量
        // 成员方法
        void set(Object obj, Object value): 设置指定对象的成员变量的值
        Object get(Object obj): 获取指定对象的成员变量的值
        void setAccessible(boolean flag): 传true时忽略访问权限修饰符的安全检查. 暴力反射

java.lang.reflect.Constructor<T>: 表示一个构造方法
        // 成员方法
        T newInstance(Object... initargs): 使用当前构造方法传入参数, 创建对象
        void setAccessible(boolean flag): 注意: 构造方法不能利用此方法忽略权限, 会抛异常

java.lang.reflect.Method类: 表示一个成员方法
        // 成员方法
        Object invoke(Object obj, Object... args): 使用指定对象和指定参数值调用此方法
        String getName(): 获取方法名
        void setAccessible(boolean flag): 传true时忽略访问权限修饰符的安全检查. 暴力反射

java.lang.ClassLoader: 类加载器
        // 成员方法
        InputStream getResourceAsStream(String name): 读取相对于bin目录中的文件, 返回一个字节流

常用元注解:
        @Target: 描述注解能够作用的位置
                ElementType枚举的常用取值:
                        TYPE:可以作用于类上
                        METHOD:可以作用于方法上
                        FIELD:可以作用于成员变量上
                示例: @Target(value = {ElementType.TYPE, ElementType.METHOD})
        @Retention: 描述注解被保留的阶段
                RetentionPolicy枚举的取值:
                        SOURCE: 保留到源代码阶段
                        CLASS: 保留到类对象阶段
                        RUNTIME: 保留到运行时阶段
                示例: @Retention(RetentionPolicy.RUNTIME):保留注解到class字节码文件中并被JVM读取到
        @Documented: 加上后, 当前注解会被抽取到api文档中
        @Inherited: 加上后, 当前注解会被子类继承
java.lang.Class<T>
        // 成员方法
        ClassLoader getClassLoader(): 返回该类的类加载器

java.lang.ClassLoader: 类加载器 加载.class文件到内存的方法区中, 其他类型文件.properties
        // 成员方法
        InputStream getResourceAsStream(String name): 读取相对于 out/production/模块名 目录中的文件, 返回一个字节流


使用类加载器加载配置文件
        // 随便获取一个类的字节码对象
        Class clazz = 类名.class;
        // 用字节码对象获取类加载器, 可加载bin目录中编译的文件
        ClassLoader classLoader = clazz.getClassLoader();
        // 使用类加载器加载一个文件, 返回一个字节流
        InputStream is = classLoader.getResourceAsStream("相对于src目录的相对路径");
        // 有了字节流, 就可以使用Properties的load(InputStream in)方法读取配置
        Properties p = new Properties();
        p.load(is);
        String value = p.getProperty("key");
自定义注解格式:关键字 @interface


    元注解
    public @interface 注解名称 {
        属性; (接口中的抽象方法)
            属性;
            属性;
            ...
    }

@注解名称
属性:
        接口中的"抽象方法"

属性的要求:
    1. 属性的"返回值类型"可以是以下类型:
        基本数据类型(8种)
        String
        枚举
        注解
        以上类型的数组
    2. 定义了属性,在使用注解时, 需要"给属性赋值" (其实是抽象方法的返回值)
        1. 属性使用 default 关键字指定默认值, 则可以不赋值
        2. 如果只有一个名为"value"的属性需要赋值, 则 value 可以省略, 直接写值即可
        3. 给数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}可以省略
元注解:
        用于描述注解的注解

常用元注解:
        @Target: 描述注解能够作用的位置
                ElementType枚举的常用取值:
                        TYPE:可以作用于类上
                        METHOD:可以作用于方法上
                        FIELD:可以作用于成员变量上
                示例: @Target(value = {ElementType.TYPE, ElementType.METHOD})
        @Retention: 描述注解被保留的阶段
                RetentionPolicy枚举的取值:
                        SOURCE: 保留到源代码阶段
                        CLASS: 保留到类对象阶段
                        RUNTIME: 保留到运行时阶段
                示例: @Retention(RetentionPolicy.RUNTIME):保留注解到class字节码文件中并被JVM读取到
        @Documented: 加上后, 当前注解会被抽取到api文档中
        @Inherited: 加上后, 当前注解会被子类继承
获取注解属性值的步骤:
        1. 获取注解定义位置的对象 (Class对象(类注解), Field对象(成员变量注解), Method对象(方法注解))
        2. 调用 ProAnno a = cls.getAnnotation(ProAnno.class) 方法获取注解对象
        3. 通过注解对象调用抽象方法获取属性值

        // 比如获取一个类上的注解
    注解类型 注解变量名 = 被注解的类.class.getAnnotation(注解名.class);
    数据类型 变量名 = 注解变量名.抽象方法();

    ProAnno proAnno = Test.class.getAnnotation(ProAnno.class);
    String className = proAnno.className();
    String methodName = proAnno.methodName()







0 个回复

您需要登录后才可以回帖 登录 | 加入黑马