前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java常用业务代码

Java常用业务代码

作者头像
每天学Java
发布2020-06-01 10:49:18
1.5K0
发布2020-06-01 10:49:18
举报
文章被收录于专栏:每天学Java每天学Java

本篇文章将日常开发中常用的方法进行整理,涉及面有:位运算、时间处理、集合处理、反射、线程池构建、线程同步工具类、Excel解析。

位运算

位运算常用六种运算符

代码语言:javascript
复制
& 按位与, 同1为1
| 按位或, 同0位0
^ 异或,两个位相同为0,相异为1
~ 取反,0转1,1转0
>> 右移,Java中右移,符号位不变,左边补上符号位
<< 左移,各二进位全部左移若干位,高位丢弃,低位补0

常用业务场景有:判断奇偶数,判断是否为2的整数次幂,左移,右移,两数交换,取相反数,取绝对值。

代码语言:javascript
复制
    //====位运算
    private void bitOperation() {
        int n = -8, m = 8;
        System.out.println("是否为奇数:" + ((n & 1) == 1));
        System.out.println("是否为2的整数次幂:" + ((n & (n - 1)) == 0));
        System.out.println("左移动:" + (n << 1));
        System.out.println("右移动:" + (n >> 1));
        System.out.println("无符号右移动:" + (n >>> 1));
        System.out.println("因为左移是右测补0,不存在符号问题,所以不存在无符号左移动,");
        //交换
        n ^= m;
        m ^= n;
        n ^= m;
        System.out.println("交换后n=" + n + ",m=" + m);
        System.out.println("相反数n=" + (~n + 1));
        // >> 31得到符号位
        System.out.println("绝对值m=" + ((m ^ (m >> 31)) - (m >> 31)));
        //任何整数和自己异或的结果为 0,任何整数与 0 异或其值不变
    }
时间处理

在Java8中提供了LocalDateTime和LocalDate,其中LocalDateTime用于处理日期时间,LocalDate用于处理日期。

常用业务有:格式化日期,判断周几,获取上一个周几,获取两日期之间时间间隔,获取两日期之间工作日

代码语言:javascript
复制
    //====处理日期
    private void handlerDate() {
        //======格式化日期
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dfd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        //当前时间 注意LocalDateTime为final
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(df.format(ldt));
        //自定义日期时间
        ldt = LocalDateTime.parse("2020-05-20T10:15:30");
        System.out.println(df.format(ldt));
        //======判断是周几
        System.out.println("周" + ldt.getDayOfWeek().getValue());
        //======获取上一个周四
        while (ldt.getDayOfWeek() != DayOfWeek.THURSDAY) {
            ldt = ldt.plusDays(-1);
        }
        System.out.println("上一个周四时间:" + df.format(ldt));
        //======时间间隔
        Duration duration = Duration.between(ldt, LocalDateTime.now());
        System.out.println("相差" + duration.toDays() + "日");
        System.out.println("相差:" + duration.toHours() + "小时");
        System.out.println("相差:" + duration.toMinutes() + "分钟");
        System.out.println("相差:" + duration.toMillis() + "毫秒");
        //=======获取日期之间的工作日
        List<String> list = new ArrayList<>();
        while (ldt.isBefore(LocalDateTime.now())) {
            if (ldt.getDayOfWeek() != DayOfWeek.SUNDAY && ldt.getDayOfWeek() != DayOfWeek.SATURDAY) {
                list.add(dfd.format(ldt));
            }
            ldt = ldt.plusDays(1);
        }
        System.out.println(list);
    }
集合处理

集合List使用十分常见,对于集合处理常见业务场景有:自然排序,倒叙,中文排序,数据过滤,去重,转Map分组,分组统计

Map中常用场景为遍历

代码语言:javascript
复制
    //===处理List
    private void handlerList() {
        //=====List
        List<String> list = Arrays.asList("1,2,1,3,4,5".split(","));
        //排序
        List<String> temp = list.stream().sorted((o1, o2) -> {
            //倒序
            return o2.compareTo(o1);
        }).collect(Collectors.toList());
        System.out.println(temp);
        //中文排序
        List<String> words = Arrays.asList("每,天,学,J,A,V,A".split(","));
        temp = words.stream().sorted((o1, o2) -> {
            //倒序
            return Collator.getInstance(Locale.CHINESE).compare(o1, o2);
        }).collect(Collectors.toList());
        System.out.println(temp);
        //将字段为 1 的数据过滤掉
        temp = list.stream().filter(s -> !s.equals("1")).collect(Collectors.toList());
        System.out.println(temp);
        //去重
        temp = list.stream().distinct().collect(Collectors.toList());
        System.out.println(temp);
        //转Map
        Map<String, List<String>> map2 = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.toList()));
        System.out.println(map2);
        //分组计数
        Map<String, Long> map = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        System.out.println(map);
    }
        //===处理Map
    private void handlerMap() {
        //=====Map
        //遍历Map
        Map<String, String> map = new HashMap<>();
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entrie : entries) {
            System.out.println(entrie.getKey());
            System.out.println(entrie.getValue());
        }
    }
反射

日常开发中,反射也是常用手段,通常通过反射获取对象的字段,方法,字段赋值,方法调用,利用注解对字段进行注入等操作.

代码语言:javascript
复制
    //====反射
    private void handerReflect() throws IllegalAccessException, InvocationTargetException {
        //获取所有字段
        Class<?> clazz = this.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("字段名称:" + field.getName());
            System.out.println("字段类型:" + field.getType().toString());
            System.out.println("是否为接口:" + field.getType().isInterface());
            System.out.println("字段注解数量:" + field.getDeclaredAnnotations().length);
            //赋值
            field.setAccessible(true);
            field.set(this, "每天学Java");
            System.out.println("字段值:" + field.get(this));
        }
        //获取所有的方法
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("方法名称:" + method.getName());
            System.out.println("方法返回类型:" + method.getReturnType());
            System.out.println("方法参数:" + method.getParameterTypes());
            //调用 method.invoke()
        }
    }
线程池构建

通常我们会通过Executors来创建线程池,但是其底层也是使用ThreadPoolExecutor,面试中关于ThreadPoolExecutor的参数构造也是常见的面试题

代码语言:javascript
复制
    //====线程池
    private ThreadPoolExecutor threadPool() {
        //核心线程数量
        int corePoolSize = 5;
        //最多线程数
        int maximumPoolSize = 10;
        //非核心线程保活时间
        long keepAliveTime = 1;
        //保活单位
        TimeUnit unit = TimeUnit.MINUTES;
        //阻塞队列
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        //创建线程工厂类
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        //拒绝策略
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler
        );
        return threadPoolExecutor;
    }
线程同步工具类

使用多线程的目的是为了实现异步,但特定场景下,我们想要局部异步,最终同步,比如使用多个线程统计每个省份的用户量,最终通过线程同步工具类其聚合。

代码语言:javascript
复制
    //====线程同步工具
    private void latchUtil() throws InterruptedException {
        //CountDownLatch 一次控制
        Executor executor = threadPool();
        CountDownLatch latch = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            executor.execute(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 运行");
                latch.countDown();
            });
        }
        System.out.println("等待所有线程执行结束");
        latch.await(1, TimeUnit.MINUTES);
        System.out.println("所有线程执行结束");
        //CyclicBarrier 循环多次控制
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
        for (int i = 0; i < 5; i++) {
            executor.execute(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                try {
                    System.out.println(Thread.currentThread().getName() + " 第一批次运行");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName() + " 第二批次运行 ");
                    cyclicBarrier.await();
                    System.out.println("结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }

            });
        }
        ((ExecutorService) executor).shutdown();
    }
Excel解析

使用Excel完成批量导入功能是常见的功能,通过我们会利用POI包来实现这一功能,具体过程:拿到文件流,对Excel每一个Sheet页的字段进行校验,整理,保存,最终进行导入。

依赖:

代码语言:javascript
复制
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.11-beta2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.11-beta2</version>
        </dependency>

代码过长,建议收藏哦!

代码语言:javascript
复制
    //解析Excel表格
    private void handlerExcel(String filePath, boolean isLocal) throws IOException, InvalidFormatException {
        InputStream inputStream = null;
        if (isLocal) {
            inputStream = new FileInputStream(new File(filePath));
        } else {
            URL url = new URL(filePath);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setReadTimeout(50000);
            inputStream = urlConnection.getInputStream();
        }

        Workbook workbook = WorkbookFactory.create(inputStream);
        handlerSheet(workbook);
    }

    private void handlerSheet(Workbook workbook) {
        //sheet页面数量
        int sheets = workbook.getNumberOfSheets();
        Sheet currentSheet = null;
        for (int i = 0; i < sheets; i++) {
            Map<Integer, String> field = new HashMap<>();
            List<Object> objects = new ArrayList<>();
            currentSheet = workbook.getSheetAt(i);
            System.out.println("处理sheet页面:" + currentSheet.getSheetName());
            System.out.println("sheet页面行数" + (currentSheet.getLastRowNum() - currentSheet.getFirstRowNum()));
            //获取第一行表头字段
            tableHead(field, currentSheet);
            //获取内容
            for (int j = 1; j <= currentSheet.getLastRowNum(); j++) {
                Object o = tableContent(field, currentSheet.getRow(j));
                objects.add(o);
            }
            //TODO:得到完整对象,进入验证导入

        }
    }

    private void tableHead(Map<Integer, String> field, Sheet sheet) {
        Row row = sheet.getRow(0);
        int cellIndex = 0;
        for (Cell cell : row) {
            //全部以字符串形式读取
            cell.setCellType(Cell.CELL_TYPE_STRING);
            String name = getValue(cell).toString();
            //TODO:可以name转换为key,后面通过反射进行注入
            field.put(cellIndex++, name);
        }
    }

    private Object tableContent(Map<Integer, String> fieldMap, Row row) {
        int cellIndex = 0;
        //TODO:替换为自定义对象字段,或使用Map返回,由调用方进行set
        Object o = new Object();
        for (Cell cell : row) {
            //全部以字符串形式读取
            cell.setCellType(Cell.CELL_TYPE_STRING);
            //获取单元格名称
            String value = getValue(cell).toString();
            //获取字段名称
            String fieldName = fieldMap.get(cellIndex++);
            Field field = null;
            try {
                field = o.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                field.set(o, value);
            } catch (NoSuchFieldException e) {
                System.out.println("字段不存在:" + fieldName);
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                System.out.println("赋值字段不合法:" + field.getType() + "<-String");
                e.printStackTrace();
            }
        }
        return null;
    }

    private Object getValue(Cell cell) {
        //日期需要特殊处理
        Object o = null;
        switch (cell.getCellType()) {
            case 0:
                o = cell.getNumericCellValue();
                break;
            case 1:
                o = cell.getStringCellValue();
                break;
            case 2:
                o = cell.getCellFormula();
                break;
            case 3:
                o = "";
                break;
            case 4:
                o = cell.getBooleanCellValue();
                break;
            case 5:
                o = cell.getErrorCellValue();
                break;
            default:
                break;
        }

        return o;
    }
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 位运算
  • 时间处理
  • 集合处理
  • 反射
  • 线程池构建
  • 线程同步工具类
  • Excel解析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档