直接使用stream流

public class Stream {public static void main(String[] args) {
    //ArrayList<Object> arrayList = new ArrayList<>(); //List集合不安全,stream().parallel()操作不行

    List<Object> arrayList = Collections.synchronizedList(new ArrayList<>());//解决方法一:集合工具类
 // CopyOnWriteArrayList<Object> arrayList = new CopyOnWriteArrayList<>(); //解决方法二:JUC的集合
    for (int i = 1; i <= 100000; i++) {
        arrayList.add(String.valueOf(i));
    }
    System.out.println("-------------------使用串行流--------------------");
    ArrayList<Object> result1 = new ArrayList<>();
    long start = System.currentTimeMillis();
    arrayList.forEach((str)->{
//        System.out.println(Thread.currentThread().getName()+",操作中。。。");
        result1.add(new User(2, (String) str,22));
    });
  //  System.out.println("使用串行流,修改集合"+result1);
    System.out.println("花费的时间为:"+(System.currentTimeMillis()-start));

    System.out.println("-------------------使用并行流--------------------");
    //这里使用的集合需要注意,不能使用常规的集合,在扩容的时候会出现数组下标越界异常,经过测试CopyOnWriteArrayList集合效率比较低下,因为CopyOnWriteArrayList,在写操作的时候会新建集合
    List<Object> result2 = Collections.synchronizedList(new ArrayList<>());
  //CopyOnWriteArrayList<Object> arrayList = new CopyOnWriteArrayList<>();
    start = System.currentTimeMillis();
    arrayList.stream().parallel().forEach((str)->{
        //System.out.println(Thread.currentThread().getName()+",操作中。。。");
        result2.add(new User(2, (String) str,22));
    });
 //   System.out.println("使用并行流,修改集合"+result2);
    System.out.println("花费的时间为:"+(System.currentTimeMillis()-start));
}

}

add操作使用的集合需要注意,不能使用常规的集合,在扩容的时候会出现数组下标越界异常,经过测试CopyOnWriteArrayList集合效率比较低下,因为CopyOnWriteArrayList,在写操作的时候会新建集合,JUC包下的一些集合是可以用的,或者是加锁的集合,但是效率不一定会很高,数据量太大也会导致内存泄漏OOM问题

 使用IntStream流

@Test
    public void testStream(){
        IntStream intStream = IntStream.of(6, 1, 1, 2, 5, 2, 3, 4);
        long start=System.currentTimeMillis();
        //并行处理
        intStream.parallel().forEach(x->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+x);
        });
        System.out.println("parallel time->"+(System.currentTimeMillis()-start));

        intStream = IntStream.of(6, 1, 1, 2, 5, 2, 3, 4);
        start=System.currentTimeMillis();
        //默认都是串行处理
        intStream.sequential().forEach(x->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+x);
        });
        System.out.println("sequential time->"+(System.currentTimeMillis()-start));
    }

 在使用并行流的时候一定要注意线程安全问题,而且并不能保证多个线程之间顺序执行,多线程还需要考虑原子性可见性指令重排等问题,而且效率也不一定会比串行流高很多,在使用的时候需要慎重考虑优劣,毕竟带来的问题还是比较多的

查询表中是否存在想要的记录:

select 1 from table where  。。。 limit 1

在queryMapper后拼接limit条件:

String 中就是sql语句例如:"limit 1"

querymapper.last(String)

遇到很多个表结构差不多的情况,使用反射加上泛型就可以封装一个通用的mapper,这个就是随便写的一个Demo,不一定对,随便瞎写的,大概就是这个意思

public <T,R> R baseMapper(R request,Class<T> po){

QueryMapper<T> queryMapper=new QueryMapper();
//这里使用反射获取request的属性,然后拼接mapper条件,其实就相当于写死了,然后判断属性值是否为null,来拼接sql
queryMapper.eq("name",request.hetClass().getgetDeclaredField("name").get(request));
//这里如果属性是私有的话,可以setAccessible(true),来破坏私有属性
return queryMapper;

}

idea当前类全局替换: ctrl+r  ,还可以排除不想替换的词

idea大小写转换快捷键:ctrl+shift+u

idea全局替换:ctrl+shift+r

获取ip地址,这个在多节点情况下对于排查问题时是很有必要的:

InetAddress.getLocalHost().getHostAddress()

 stream流将两个集合合并成一个map,一个集合的值当key,一个集合的值为value;这里需要注意key的唯一性问题

public static void main(String[] args) {

        List<Integer> keyList = new ArrayList<>();
        List<String> valueList = new ArrayList<>();
        keyList.add(1);
        keyList.add(2);
        keyList.add(3);
        keyList.add(4);
        keyList.add(5);
        valueList.add("张三");
        valueList.add("李四");
        valueList.add("王五");
        valueList.add("赵六");
        valueList.add("钱七");
        //使用stream流的方式,把这两个list集合长度一样合并成一个map集合
        //将list转换map
        Map<Object, Object> map = keyList.stream().collect(Collectors.toMap(key -> key, value -> valueList.get(keyList.indexOf(value))));
        System.out.println(map);
        //最终需要的结果 {1=张三, 2=李四, 3=王五, 4=赵六, 5=钱七}
    }

 从一个集合中截取指定区间的数据:

ArrayList.subList() ; (左开右闭)

boolean类型的参数尽量不要用is来命名,因为某些框架会自动将Boolean类型参数的is去掉

private Boolean isShow;  ->  private boolean show;

 将两个集合合并成一个集合

List<String> list1 = Arrays.asList("阿卫", "阿辉", "阿杰", "阿成");
         List<String> list2 = Arrays.asList("阿悦", "阿楠", "阿洁", "阿锋");
         Stream.concat(list1.stream(),list2.stream());

 时间类型作比较

before()和after()方法  必须格式一致

compareTo()方法 返回boolean类型

或者将时间转换为毫秒作比较  getTime()方法

stream流分组排序

LinkedHashMap<Integer, List<Person>> ageMap = persons.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(Collectors.groupingBy(Person::getAge, LinkedHashMap::new, Collectors.toList()));

 多字段排序

//先以userId降序,再进行userName升序 **推荐使用该种方式**
     list =  list.stream().sorted(Comparator.comparing(User::getUserId,Comparator.reverseOrder()).thenComparing(User::getUserName)).collect(Collectors.toList());

 数组进行翻转

Collections.reverse(arrayList)

 自定义常量集合

/** 常量值列表 */
     public static final List<Integer> CONST_VALUE_LIST = Collections.unmodifiableList(Arrays.asList(1, 2, 3));
     /** 常量值集合 */
     public static final Set<Integer> CONST_VALUE_SET = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(1, 2, 3)));
     /** 常量值映射 */
     public static final Map<Integer, String> CONST_VALUE_MAP;
     static {
         Map<Integer, String> valueMap = new HashMap<>();
         valueMap.put(1, "value1");
         valueMap.put(2, "value2");
         valueMap.put(3, "value3");
         CONST_VALUE_MAP = Collections.unmodifiableMap(valueMap);
     }

 分割字符串

String dirDiveded[] = fileName.split("/"); String newName = ""; if(dirDiveded.length > 0){ newName = dirDiveded[dirDiveded.length-1]; }
 String newName = fileName.substring(fileName.lastIndexOf("/")+1);

http下载

public static void download(List urlStringList) {
         OutputStream os = null;
         InputStream is = null;
         try {
             for (Object urlStringObj : urlStringList) {
                 String urlString = (String) urlStringObj;
                 // 构造URL
                 URL url = new URL(urlString);
                 // 打开连接
                 URLConnection con = url.openConnection();
                 //设置请求超时为5s
                 con.setConnectTimeout(5 * 1000);
                 // 输入流
                 is = con.getInputStream();
                 // 1K的数据缓冲
                 byte[] bs = new byte[1024];
                 // 读取到的数据长度
                 int len;
                 // 路径
                 String filename = urlString.substring(urlString.lastIndexOf("/"));
 //                System.out.println(filename);
 //                String str = urlString.split(filename)[0];
 //                System.out.println(str);
 //                String[] split = str.split("//");
 //                int i = split[1].indexOf("/");
 //                String substring = split[1].substring(i);
 //                System.out.println(substring);
  
                 // 输出的文件流
                 File sf = new File(savePath);
                 if (!sf.exists()) {
                     sf.mkdirs();
                 }
                 os = new FileOutputStream(sf.getPath() + filename+fileType);
                 // 开始读取
                 while ((len = is.read(bs)) != -1) {
                     os.write(bs, 0, len);
                 }
 //                System.out.println("下载完成");
             }
             // 完毕,关闭所有链接
             os.close();
             is.close();
         }catch (Exception e){
             e.printStackTrace();
         }finally {
             try {
                 if(null != os){
                     os.close();
                 }
                 if(null != is){
                     is.close();
                 }
             }catch (Exception e){
                 e.printStackTrace();
             }
         }
  
     }

异常处理:Cannot call sendError() after the response has been committed

 原因是在流关闭之后接口还返回了数据,使接口返回void即可解决

 Protocol handler start failed :端口占用

返回流设置类型:

response.setContentType("multipart/form-data");

 返回流,设置文件名称中文失效:

response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));

 异常处理:getOutputStream() has already been called for this response

在getOutputStream()和getWriter()中间,使用respomse.reset()方法

 日志打印:

log.error("BasicFileFacade的update()方法不成功,参数为{}",updateFileRequest);

 BigDecimal科学计数法问题

科学计数法:toString()
不使用科学计数法:toPlainString()

Java8 Stream 流中的匹配查找方法

findAny:查找任何一个就返回 Optional
findFirst:查找到第一个就返回 Optional
anyMatch:匹配上任何一个则返回 Boolean allMatch:匹配所有的元素则返回 Boolean

public enum SwitchEnum {
    ONE(1, "x"),
     TWO(2, "x"),
     THREE(3, "x2");    private int type;
     private String name;    SwitchEnum(int type, String name) {
         this.type = type;
         this.name = name;
     }    // 查找某一个枚举值
     public static SwitchEnum findAny(int type) {
         return Arrays.stream(SwitchEnum.values())
                 .filter(switchEnum -> switchEnum.getType() == type)
                 .findAny()
                 .orElse(null);
     }    // 匹配到第一个枚举值就返回
     public static SwitchEnum findFirst(String name) {
         return Arrays.stream(SwitchEnum.values())
                 .filter(switchEnum -> switchEnum.getName().equals(name))
                 .findFirst()
                 .orElse(null);
     }     // 枚举匹配
     public static boolean anyMatch(int type) {
         return Arrays.stream(SwitchEnum.values())
                 //匹配任何一个则返回
                 .anyMatch(switchEnum -> switchEnum.getType() == type);
     }    // 枚举匹配
     public static boolean allMatch(String name) {
         return Arrays.stream(SwitchEnum.values())
                 //匹配所有
                 .allMatch(switchEnum -> switchEnum.getName().equals(name));
     }     public int getType() {
         return type;
     }     public String getName() {
         return name;
     }    public static void main(String[] args) {
         System.out.println("findAny============>" + findAny(1));
         System.out.println("findFirst============>" + findFirst("x"));
         System.out.println("anyMatch============>" + anyMatch(2));
         System.out.println("anyMatch============>" + allMatch("x"));
     }
 }


 

 fifter使用:fifter留下的是过滤条件中为true的

public class StreamTest{
     public static void main(String[] args){
         List<User> list = new ArrayList<>();
         //定义三个用户对象
         User user1 = new User();
         user1.setUsername("huxiansen");
         user1.setPassword("123456");
         User user2 = new User();
         user2.setUsername("huxianseng");
         user2.setPassword("123456");
         User user3 = new User();
         user3.setUsername("huxiansen");
         user3.setPassword("12345");
         //添加用户到集合中
         list.add(user1);
         list.add(user2);
         list.add(user3);
 
         //在集合中查询用户名为huxiansen的集合
         List<User> userList = list.stream().filter(user -> "huxiansen".equals(user.getUsername())).collect(Collectors.toList());
         //在集合中查询出第一个用户密码为123456的用户
         Optional<User> user = list.stream().filter(userTemp -> "123456".equals(userTemp.getPassword())).findFirst();
 
         System.out.println(userList);
         System.out.println(user);
     }
 }```


 

 stream去重:

distinct()

list.stream().dintnct().map()   这样是对整体去重
 list.stream().map().dintinct()   这样是对map之后的结果去重

stream分组

Map <String,List <QueryPensionIncome>>collect1=queryPensionIncomeList.stream().collect(Collectors.groupingBy(QueryPensionIncome::getIncomeDate));

函数式编程 

其实写法就和stream流差不多,就是将方法作为参数传递进另一个方法,来执行一些逻辑

 

public interface TestInterface<T> {

    void execute(TestInterface2<T> message, Integer integer);

    void doSend(String message);
}

定义这个接口得实现

@Component
public class TestInterfaceImpl implements TestInterface{


    @Override
    public void execute(TestInterface2 message, Integer integer) {
        System.out.println(integer);
        if (message!=null){
            System.out.println("sss");
        }
        message.execute("sss",1);
    }


    @Override
    public void doSend(String message) {
        System.out.println("发送成功");
    }
}

 

然后定义一个接口用来调用,这个接口不用写实现 ,用抽象类也可以

@FunctionalInterface
public interface TestInterface2<T> {

    void execute(String message, Integer integer);
}

写一个测试类测试一下

@Test
public void testMain() {
    testInterface.execute((message, integer) -> {
        System.out.println("interface");
        testInterface.doSend("xxxx");
        System.out.println(integer);
        System.out.println(message);
    }, 1);
}

 

如有其他问题评论区见