Ver Fonte

24 25 代码

fanjialong há 9 meses atrás
pai
commit
ca081c66d4

+ 2 - 0
src/main/java/com/sf/day24/_03_stream/dt/Product.java

@@ -9,4 +9,6 @@ public class Product {
     private Long id;
     private String name;
     private Integer price;
+
+
 }

+ 35 - 0
src/main/java/com/sf/day25/_01_stream/Product.java

@@ -0,0 +1,35 @@
+package com.sf.day25._01_stream;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class Product {
+    private Long id;
+    private String name;
+    private Double price;
+
+    public static List<Product> datas = new ArrayList<>();
+    static {
+        datas.add(new Product(1L,"苹果10",3000.00));
+        datas.add(new Product(2L,"华为meto60",5000.00));
+        datas.add(new Product(3L,"苹果11",4000.00));
+        datas.add(new Product(4L,"苹果12",6500.00));
+        datas.add(new Product(5L,"华为meta70",5000.00));
+    }
+
+    @Deprecated
+    public void eat(){
+        System.out.println("123");
+    }
+
+    public void eatNew(){
+        System.out.println("这是新的方法");
+    }
+}

+ 196 - 0
src/main/java/com/sf/day25/_01_stream/StreamTest.java

@@ -0,0 +1,196 @@
+package com.sf.day25._01_stream;
+
+import org.junit.Test;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class StreamTest {
+
+    @Test
+    public void test(){
+        // 1 创建出来一个结合
+        List<Integer> list = Arrays.asList(1, 2,3,4, 4, 3,11,9, 5,7,8,9);
+        // 2 获取stream 流
+        // 3 想要把集合当中每一个元素的值都加5
+        list.stream().
+                filter(e -> e>3).
+                distinct().     // 去重
+                limit(5).       // 保留3条数据
+                skip(1).        // 跳过几个元素
+                map(e -> e+5 ). // 对于我们元素进行额外处理
+                sorted((o1, o2) -> o2-o1).   // 如果想要从小到大排序直接调用sorted 如果想要从大到小进行排序需要传入比较器
+                forEach(System.out::println);
+    }
+
+    @Test
+    public void test1(){
+        /**
+         * 定义一个集合   1,5,5,4,3,2,1,
+         * 1要求进行去重
+         * 2要求过滤大于3
+         * 3最后求一共有多个大于3的元素 , 总数量
+         * 4求最大值 和最小值
+         */
+//        List<Integer> list = Arrays.asList(1, 5, 5, 4, 3, 2, 1);
+//        List<Integer> list1 = new ArrayList<>();
+//        list.stream().
+//                distinct().
+//                filter(e-> e>3).
+//                forEach(e-> list1.add(e));
+//        System.out.println("总数量:"+ list1.size());
+//        System.out.println("最大值:"+Collections.max(list1));
+//        System.out.println("最小值:"+ Collections.min(list1));
+
+        List<Integer> list = Arrays.asList(1, 5, 5, 4, 3, 2, 1);
+        // option 是jdk8 提供一个类
+        // 他封装了我们想要数据, 如果你想要拿到我们数据,需要调用get 方法
+        Optional<Integer> optional = list.stream().
+                distinct().
+                filter(e -> e > 3).    //中间操作
+                // 注意终止操作要在中间操作后面
+//              count();   // 总数量
+//              max((o1, o2) -> o1 - o2);    自己传入比较器
+                // 这里Comparator.naturalOrder() 返回比较器,用的升序排序 ,如果要降序还是要自己传入比较器
+//              max(Comparator.naturalOrder());
+//              min(Comparator.naturalOrder());    // jdk 8 当中提供新的方法返回自然排序比较器
+                min(Integer::compareTo);           // 包装类当中提供一个方法返回一个比较器
+//        System.out.println("总数量:"+ count);
+//        System.out.println("最大值:"+ optional.get());
+        // 使用option封装数据有什么好处呢 , 他提供一个方法ifPresent 判断数据是否存在 如果存在在获取数据
+        System.out.println("最小值:"+ optional.get());
+
+
+        /**
+         * 总结: 针对基本类型的比较求最大值和最小值写法一共有三种方式
+         * max((o1, o2) -> o1 - o2);  自己传入比较器, 写比较规则
+         * max(Comparator.naturalOrder());  jdk8 提供新方法,返回自然排序比较器
+         * min(Integer::compareTo);  包装类当中提供方法返回自然排序比较器   从小到大进行排序
+         * 自己选择一种去记
+         */
+
+    }
+
+
+    @Test
+    public void test2(){
+        // 需求:
+        // 如果是华为手机折扣要打8折, 如果是苹果手机打9折扣  map
+        // 实战需求:获取产品列表中价格最高的产品  使用stream 流当中max 方法实现
+        // List<Product> list  (id,name,price)  要求在静态代码框中完成初始化
+        Optional<Product> optional = Product.datas.stream().
+                map(e -> {
+                    // 判断如果e.getName 是苹果打9折 如果是华为就打8折
+                    double price;
+                    if (e.getName().contains("苹果")) {
+                        price = e.getPrice() * 0.9;
+                    } else if (e.getName().contains("华为")) {
+                        price = e.getPrice() * 0.8;
+                    } else {
+                        price = e.getPrice();
+                    }
+                    e.setPrice(price);
+                    return e;
+                }).max((o1, o2) -> o1.getPrice().intValue() - o2.getPrice().intValue());
+        System.out.println(optional.get());
+    }
+
+
+    @Test
+    public void test3() {
+        // 需求:
+        // 如果是华为手机折扣要打8折, 如果是苹果手机打9折扣  map
+        // List<Product> list  (id,name,price)  要求在静态代码框中完成初始化
+        // 要求把数据最终存到List ,Set
+        List<Product> list = new ArrayList<>();
+        Set<Product> set = new HashSet<>();
+        Set<Product> list1 = Product.datas.stream().
+                map(e -> {
+                    // 判断如果e.getName 是苹果打9折 如果是华为就打8折
+                    double price;
+                    if (e.getName().contains("苹果")) {
+                        price = e.getPrice() * 0.9;
+                    } else if (e.getName().contains("华为")) {
+                        price = e.getPrice() * 0.8;
+                    } else {
+                        price = e.getPrice();
+                    }
+                    e.setPrice(price);
+                    return e;
+                }).collect(Collectors.toSet());
+        System.out.println(list1);
+
+
+    }
+
+    @Test
+    public void test4(){
+        // 需求2 : List<Integer> {1,2,3,4,5,6}
+        // 要求过滤大于3的
+        // 保留2个
+        // 要求最终把数据放到一个map<Integer,Integer> 中
+        //                           4       16
+        //                           5       25
+        //
+        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
+        Map<Integer, Integer> map = list.stream().
+                filter(e -> e > 3).
+                limit(2).collect(Collectors.toMap(e -> e, e -> e * e));
+        System.out.println(map);
+    }
+
+    /**
+     * 需求: List<Integer> {1,2,5,3,4,5,6}
+     * 要求 求出集合当中4 5 6 的总和和平均值 第一第二第三大的元素 具体怎么找到4 5 6 自己想办法
+     * 要求求平均值和总和
+     */
+    @Test
+    public void test5(){
+        List<Integer> list = Arrays.asList(1, 2, 5, 3, 4, 5, 6);
+        // 定义综合
+//        Integer count = 0;
+//
+//        // 集合数据进行去重, 并且排序, 并且放到新的集合中
+//        List<Integer> list1 = list.stream().
+//                distinct().
+//                sorted((o1, o2) -> o2 - o1).collect(Collectors.toList());
+//        // 遍历新的集合判断小于3 求和
+//        for (int i = 0; i < list1.size(); i++) {
+//            if(i<3){
+//                count += list1.get(i);
+//            }
+//        }
+//        System.out.println(count);
+//        System.out.println(count/3);
+        // 最开始求4,5,6    4平方 + 5平方+ 6平方
+        Integer count = list.stream().
+                distinct().
+                sorted((o1, o2) -> o2 - o1).
+                limit(3).
+//                map(e-> e*e).
+                collect(Collectors.summingInt(e -> e*e));
+        System.out.println(count);
+
+//        Double dou = list.stream().
+//                distinct().
+//                sorted((o1, o2) -> o2 - o1).
+//                limit(3).
+//                collect(Collectors.averagingInt(e -> e));
+//        System.out.println(dou);
+//                collect(Collectors.summingInt(e -> e));
+    }
+
+    @Test
+    public void test6(){
+        Product product = new Product();
+        // 这里有个问题现在我们又两个方法 , 我们怎么知道那个是新的方法, 那个是旧的方法呢已经过时了呢
+        // 你如果提供Deprecated 他就会在方法上加上一个 --- 表示已经过期了
+        // 这个注解的作用 , 程序检索到以后标记---
+        /**
+         * 每一个注解作用都是不一样的, 我们学习到时候需要学习每一个注解都有什么作用
+         * @Getter 提供get 方法的 @Test 提供junit测试 Deprecated  标记方法过时的
+         */
+        product.eat();
+
+    }
+}

+ 61 - 0
src/main/java/com/sf/day25/_02_anno/AnnoTest.java

@@ -0,0 +1,61 @@
+package com.sf.day25._02_anno;
+
+import com.sf.day25._02_anno.anno.ConfigurationProperties;
+import com.sf.day25._02_anno.dt.Data;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class AnnoTest {
+
+    @Test
+    public void test() throws IOException {
+        // 解析注解的程序
+        // 想要做的事情, 是要把db.properties 文件当中属性获取出来, 设置到Data 字段中
+        // Properties  反射
+        // 1 获取字节码对象
+        Class<Data> clz = Data.class;
+        // 2 通过字节码对象获取字节码头上注解 clz.getAnnotaion(ConfigurationPropertise.class);
+        ConfigurationProperties annotation = clz.getAnnotation(ConfigurationProperties.class);
+        // 3 通过注解获取到他value 属性: db.properties
+        String value = annotation.value();
+        // 4 通过当前线程类加载器获取到 db.properties当中信息放到InputStream  Thread.currentThread();
+        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(value);
+        // 5 创建Properties 对象
+        Properties properties = new Properties();
+        // 6 调用Properties.load 方法进行加载水泥杆
+        properties.load(inputStream);
+        // 7 调用Data.set方法进行把properties 当中属性设置到对象当中  proeprties.getProperty("useranme");
+        Data data = new Data(properties.getProperty("username"),properties.getProperty("password"));
+        System.out.println(data);
+//        System.out.println(data);
+    }
+
+    /**
+     * 知识点: 自定义注解 , 反射 , 自定义异常
+     * 需求: 现在在Data 当中有一个method1();
+     * 要求: 在方法的头上@RequiredLogin(value=true)注解
+     * 如果是true 表达需要登录可以访问
+     * 如果是false 表示不需要登录就可以访问
+     *
+     *
+     * 要求是在初始化代码块当中去解析注解  method.getAnnotion()
+     * 1要先获取字节码 2 获取方法 method1 3 获取注解  4 判断注解的值
+     * 最终效果
+     *   @Test
+     *     public void test2(){
+     *         Data data = new Data();
+     *         data.method1();
+     *     }
+     *  如果这个方法贴了这个注解就抛出自定义异常BusinessException("请先登录");
+     *  如果没有贴注解就可以正常进行访问
+     *
+     */
+    @Test
+    public void test2(){
+        Data data = new Data();
+        data.method1();
+    }
+}

+ 28 - 0
src/main/java/com/sf/day25/_02_anno/anno/ConfigurationProperties.java

@@ -0,0 +1,28 @@
+package com.sf.day25._02_anno.anno;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 写元注解: 就是这个注解的限制条件
+ * 限制: 在什么时期生效, 限制他能够贴在什么位置
+ * 生效时期: Runtime 运行   贴在: 类
+ * 在注解中如果你的属性名是value , 并且你只有一个属性, 那属性名可以省略不写
+ */
+//@Target({ElementType.TYPE,ElementType.METHOD})
+@Target(ElementType.TYPE)             // 限制他只能贴在类上
+@Retention(RetentionPolicy.RUNTIME)   // 表示在运行时期生效
+public @interface ConfigurationProperties {
+    // 注解当中定义的方法又叫做属性
+    // 现在我们的需求是加载配置文件, 配置文件名字是不固定的,
+    // 所以我们应该设计出来一个属性让用户可以修改, 我们也可以给他提供一个默认值叫db.properties
+    // 如果用户传递了属性就用用户的属性, 如果用户没有传递属性就用默认属性
+
+    /**
+     * 什么时候设计成一个数组,什么时候设计成一个基本类型,String
+     * 没有一个固定答案: 要看具体需求业务场景, 比如我们此时配置文件名字就一个单个字符串
+     */
+    String value() default "db.properties";  // default 就表示他的一个默认值
+}

+ 12 - 0
src/main/java/com/sf/day25/_02_anno/anno/RequiredLogin.java

@@ -0,0 +1,12 @@
+package com.sf.day25._02_anno.anno;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RequiredLogin {
+    boolean value();
+}

+ 50 - 0
src/main/java/com/sf/day25/_02_anno/dt/Data.java

@@ -0,0 +1,50 @@
+package com.sf.day25._02_anno.dt;
+
+import com.sf.day25._02_anno.anno.ConfigurationProperties;
+import com.sf.day25._02_anno.anno.RequiredLogin;
+import com.sf.day25._02_anno.ex.BusinessException;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+
+import java.lang.reflect.Method;
+
+
+@lombok.Data
+@AllArgsConstructor
+@NoArgsConstructor
+// 把自定义注解贴到类上
+@ConfigurationProperties
+public class Data {
+    private String username;
+    private String password;
+
+    {
+        //解析的业务逻辑
+        // 目标: 拿到方法头上的注解的值 进行判断
+        // 1 获取字节码信息
+        Class<Data> clz = Data.class;
+        // 2 根据字节码获取到方法
+        try {
+            Method method1 = clz.getMethod("method1");
+            // 3 根据方法获取方法头注解
+            RequiredLogin annotation = method1.getAnnotation(RequiredLogin.class);
+            // 4 根据注解获取注解当中值
+            boolean value = annotation.value();
+            // 5 判断值如果为true 抛出异常
+            if(value){
+                throw new BusinessException("请登录以后再访问");
+            }else{
+                System.out.println("无需登录就可以访问");
+            }
+            // 6 如果为false 不抛出异常
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+   @RequiredLogin(value = false)
+   public void method1(){
+       System.out.println("执行了method1");
+   }
+}

+ 10 - 0
src/main/java/com/sf/day25/_02_anno/ex/BusinessException.java

@@ -0,0 +1,10 @@
+package com.sf.day25._02_anno.ex;
+
+public class BusinessException extends RuntimeException {
+    public BusinessException() {
+    }
+
+    public BusinessException(String message) {
+        super(message);
+    }
+}