java----java工具包
- System:
- Runtime:
- Random:
- Scanner:
- Arrays:
- MessageFormat:
- Math:
- 日期:
- Comparable:
- cloneable接口:
- 数字处理:
- MD5加密:
- lambda表达式:
- RandomAccessFile:
- Properties:
- StringUtils:
- BCryptPasswordEncoder:
- beanMap和Map相互转换:
System:
System.out.println(System.currentTimeMillis());//从1970年开始,打印时间戳格式的时间 System.exit(0);//0表示正常对出
Runtime:
Runtime rt = Runtime.getRuntime(); System.out.println("处理器数量:"+rt.availableProcessors()); System.out.println("JVM总内存数:"+rt.totalMemory()); System.out.println("JVM空闲内存数:"+rt.freeMemory()); System.out.println("JVM可用最大内存数:"+rt.maxMemory()); try { rt.exec("notepad"); //调用其他的应用程序 } catch (IOException e) { e.printStackTrace(); }
Random:
生成随机数
import java.util.Random; public class Demo { public static void main(String[] args){ Random r = new Random();//如果给一个固定的数字,则生成的随机数不变 System.out.print(r.nextInt(50)); //不包含50 } }
Scanner:
键盘输入
//类似 python 中的 input import java.util.Scanner;; public class Demo { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("输入一个整数") int x = input.nextInt(); //input.next() 输入一个字符串 System.out.println(x); //0 } }
补充
InputStream in = System.in; BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); System.out.println(bufferedReader.readLine());
Arrays:
二分法查找
import java.util.Arrays; public class Demo { public static void main(String[] args){ int[] num = {1,2,3,4}; int index = Arrays.binarySearch(num, 4); //使用这个方法之前必须手动对数据进行排序。否则可能返回(-2):表示为找到 System.out.println(index); } }
原样返回一个数组
import java.util.Arrays; public class Demo { public static void main(String[] args){ int[] num = {1,2,3,4}; System.out.println(Arrays.toString(num)); } }
快速排序
comparable:可以实现自定义排序
import java.util.Arrays; public class Demo { public static void main(String[] args){ int[] num = {1,5,2,3,4}; Arrays.sort(num); System.out.println(Arrays.toString(num)); } }
数组的copy
import java.util.Arrays; public class Demo { public static void main(String[] args){ int[] num = {1,5,2,3,4}; int[] num1 = Arrays.copyOf(num, 8); //实现方式为System.arraycopy System.out.println(Arrays.toString(num1)); //[1, 5, 2, 3, 4, 0, 0, 0] num = Arrays.copyOf(num, 3); System.out.println(Arrays.toString(num)); //[1, 5, 2] } }
使用System.arraycopy 进行数组的复制
import java.util.Arrays; public class Demo { public static void main(String[] args){ int[] num1 = {1,2,3}; int[] num2 = new int[num1.length]; System.arraycopy(num1, 0, num2, 0, num1.length); System.out.print(Arrays.toString(num2)); } }
判断两个数组是否相等
import java.util.Arrays; public class Demo { public static void main(String[] args){ int[] num1 = {1,2,3}; int[] num2 = {2,3}; System.out.println(Arrays.equals(num1, num2)); } }
填充数组
import java.util.Arrays; public class Demo { public static void main(String[] args){ int[] num1 = {1,2,3}; Arrays.fill(num1, 0); System.out.println(Arrays.toString(num1)); } }
将数组拼接成字符串
StringUtils.join(new String[]{"3","c"},",");
MessageFormat:
格式化文本
import java.text.MessageFormat; public class Demo { public static void main(String[] args) { String s = "欢迎{0}"; s =MessageFormat.format(s, "小明"); System.out.println(s); } }
String.format
public class T { public static void main(String[] args) { test(); } public static void test(){ String s = "xx%s"; String str = String.format(s, "sdf"); System.out.println(str); } }
Math:
@Test public void Test1() { //三角函数和角度问题 System.out.println("sin(π/2):"+Math.sin(Math.PI / 2)); System.out.println("sin(90°):"+Math.signum(90)); System.out.println("弧度转角度:"+Math.toDegrees(Math.PI / 2)); System.out.println("角度转弧度:"+Math.toRadians(90)); //科学计算 System.out.println("4开方:"+Math.sqrt(4)); System.out.println("-10.312的绝对值:"+Math.abs(-10.312)); System.out.println("2的8次方:"+Math.pow(2,8)); //四舍五入 System.out.println("3.1四舍五入:"+Math.round(3.1)); System.out.println("3.1向上取整:"+Math.ceil(3.1)); System.out.println("3.1向下取整:"+Math.floor(3.1)); //最大最小值 System.out.println("1,2中的最大值:"+Math.max(1,2)); System.out.println("1,2中的最小值:"+Math.min(1,2)); //随机数 System.out.println("产生随机数(0~1):"+Math.random()); //对数运算 System.out.println("lg(10):"+Math.log(10)); System.out.println("lg(10):"+Math.log10(10)); }
日期:
SimpleDateFormat 使用
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; public class Demo { public static void main(String[] args) { DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss SSS"); String s = df.format(new Date()); //String s = df.format(343423); System.out.println(s); } }
public static void main(String[] args) throws ParseException { //获得bai2009年06月01日du 的Date对象 DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd"); Date myDate1 = dateFormat1.parse("2009-06-01"); System.out.println(myDate1); //获得2010年9月13日22点36分01秒zhi 的Date对象 DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date myDate2 = dateFormat2.parse("2010-09-13 22:36:01"); System.out.println(myDate2); }
df.format(new String())
calendar使用
import java.util.Calendar; public class Demo { public static void main(String[] args) { Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); int day = c.get(Calendar.DAY_OF_MONTH); int day1 = c.get(Calendar.DAY_OF_YEAR); System.out.println(year+","+day+","+day1); } }
calendar工具类
/* * 计算一个日期加上payment_freq(数字)*payment_unit(D[日],M[月],Y[年])后的日期 payment_freq 收付息周期 */ public static Date addDate(Date d, int payment_freq, String payment_unit) throws ParseException, UnitException { Calendar cal = Calendar.getInstance(); cal.setTime(d); if (payment_unit.equals("D")) { cal.add(Calendar.DAY_OF_MONTH, payment_freq); } else if (payment_unit.equals("M")) { cal.add(Calendar.MONTH, payment_freq); } else if (payment_unit.equals("Y")) { cal.add(Calendar.YEAR, payment_freq); } else { throw new UnitException(); } return cal.getTime(); }
Date 使用
import java.util.Date; public class Demo { public static void main(String[] args) { Date d = new Date(); System.out.println(d); //Thu Apr 11 14:07:40 CST 2019 } }
往数据库中插入数据是
LocalDateTime JDK1.8
System.out.println(new Date()); //Thu Sep 05 14:15:17 CST 2019 System.out.println(LocalDateTime.now()); //2019-09-05T14:15:17.480
GregorianCalendar
GregorianCalendar gregorianCalendar = new GregorianCalendar(2019, 9, 1, 19, 20,00); //Tue Oct 01 19:20:00 CST 2019 注意0是1月
java使用DateUtils对日期进行运算
maven依赖
<dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency>
使用
public class DateCalculate { /** * 日期格式的运算 * @param args */ public static void main(String[] args) { Date now = new Date(); SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("------当前时间--------:" + sd.format(now)); //年: 加、减操作 System.out.println("1年之后:"+sd.format(DateUtils.addYears(now, 1))); System.out.println("1年之前:"+sd.format(DateUtils.addYears(now, -1))); //月: 加、减操作 System.out.println("1个月之后:"+sd.format(DateUtils.addMonths(now, 1))); System.out.println("1个月之前:"+sd.format(DateUtils.addMonths(now, -1))); //周: 加、减操作 System.out.println("1周之后:"+sd.format(DateUtils.addWeeks(now, 1))); System.out.println("1周之前:"+sd.format(DateUtils.addWeeks(now, -1))); //天: 加、减操作 System.out.println("昨天的这个时候:" + sd.format(DateUtils.addDays(now, -1))); System.out.println("明天的这个时候:" + sd.format(DateUtils.addDays(now, 1))); //小时: 加、减操作 System.out.println("1小时后:" + sd.format(DateUtils.addHours(now, 1))); System.out.println("1小时前:" + sd.format(DateUtils.addHours(now, -1))); //分钟: 加、减操作 System.out.println("1分钟之后:"+sd.format(DateUtils.addMinutes(now, 1))); System.out.println("1分钟之前:"+sd.format(DateUtils.addMinutes(now, -1))); //秒: 加、减操作 System.out.println("10秒之后:"+sd.format(DateUtils.addSeconds(now, 10))); System.out.println("10秒之前:"+sd.format(DateUtils.addSeconds(now, -10))); //毫秒: 加、减操作 System.out.println("1000毫秒之后:"+sd.format(DateUtils.addMilliseconds(now, 1000))); System.out.println("1000毫秒之前:"+sd.format(DateUtils.addMilliseconds(now, -1000))); } }
两个日期间隔多少天
String dbtime1 = "2017-02-23"; //第二个日期 String dbtime2 = "2017-02-22"; //第一个日期 //算两个日期间隔多少天 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Date date1 = format.parse(dbtime1); Date date2 = format.parse(dbtime2); int a = (int) ((date1.getTime() - date2.getTime()) / (1000*3600*24)); 直接通过计算两个日期的毫秒数,他们的差除以一天的毫秒数,即可得到想要的两个日期相差的天数。
Comparable:
使用Comparable接口实现对象之间排序
package com.zy; import java.util.Arrays; public class Demo { public static void main(String[] args) { Dog[] dog = {new Dog("花花",40),new Dog("天天",20)}; Arrays.sort(dog); System.out.println(Arrays.toString(dog)); } } class Dog implements Comparable<Dog>{ private String name; private int age; public Dog(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Dog [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Dog o) { // TODO Auto-generated method stub return this.age-o.age; } }
如果对源码不修改的话使用:Comparator接口
package com.zy; import java.util.Arrays; import java.util.Comparator; public class Demo { public static void main(String[] args) { Dog[] dog = {new Dog("花花",40),new Dog("天天",20)}; Arrays.sort(dog,new DogComparator()); System.out.println(Arrays.toString(dog)); } } class Dog{ private String name; private int age; public Dog(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Dog [name=" + name + ", age=" + age + "]"; } public int getAge() { return age; } } class DogComparator implements Comparator<Dog>{ @Override public int compare(Dog o1, Dog o2) { return o1.getAge()-o2.getAge(); } }
cloneable接口:
对象的克隆
import java.util.Arrays; import java.util.Comparator; public class Demo { public static void main(String[] args) { Dog dog1 = new Dog("花花",10); try { Dog dog2 = (Dog) dog1.clone(); System.out.println(dog1); System.out.println(dog2); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class Dog implements Cloneable{ private String name; private int age; public Dog(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Dog [name=" + name + ", age=" + age + "]"; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
数字处理:
import java.math.BigDecimal; import java.math.BigInteger; import java.util.Arrays; public class Demo { public static void main(String[] args) { //大整数运算 String v1 = "8242343242343"; String v2 = "3242432424342"; BigInteger b1 = new BigInteger(v1); BigInteger b2 = new BigInteger(v2); System.out.println(b1.add(b2)); System.out.println(b1.subtract(b2)); //减法 System.out.println(b1.multiply(b2)); System.out.println(b1.divide(b2)); //取余,除法(/) System.out.println(b1.remainder(b2)); //取模(%) System.out.println(Arrays.toString(b1.divideAndRemainder(b2))); //返回一个数组 //小数运算 String v3 = "713.123213123"; String v4 = "2"; BigDecimal b3 = new BigDecimal(v3); BigDecimal b4 = new BigDecimal(v4); System.out.println(b3.add(b4)); System.out.println(b3.subtract(b4)); //减法 System.out.println(b3.multiply(b4)); System.out.println(b3.divide(b4)); //取余(/)可能会报错。原因除不尽 } }
使用方式2
BigInteger bigInteger = BigInteger.valueOf(111); BigDecimal bigDecimal = BigDecimal.valueOf(111.111); bigDecimal.add(bigDecimal); int n = bigDecimal.compareTo(bigDecimal); //比较两个数据,小于返回-1,大于返回0,等于返回0
数字格式化
import java.text.DecimalFormat; public class Demo { public static void main(String[] args) { double x = 423.64634324; //测试结果 #和0 的结果一样 System.out.println(new DecimalFormat("0").format(x)); //424; 取整数(四舍五入) System.out.println(new DecimalFormat("0.00").format(x)); //42364.63;保留两位有效数字(四舍五入) System.out.println(new DecimalFormat("0.00%").format(x)); //42364.63% System.out.println(new DecimalFormat("#").format(x)); //424;保留全部整数,和0效果一样 System.out.println(new DecimalFormat("#.##").format(x)); //42364.63 System.out.println(new DecimalFormat("#.##%").format(x)); //42364.63% //区别 System.out.println(new DecimalFormat("000000").format(x)); //000424 System.out.println(new DecimalFormat("######").format(x)); //424 long t = 2324324; System.out.println(new DecimalFormat("000,000").format(t)); //2,324,324 System.out.println(new DecimalFormat("###,###").format(t)); //2,324,324 } }
例子
DecimalFormat decimalFormat=new DecimalFormat("000"); decimalFormat.format(1) //001
MD5加密:
需要配合Base64使用,加密成Base64字符串格式
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; public class Demo { public static void main(String[] args) { try { MessageDigest md = MessageDigest.getInstance("MD5"); String password = "qwert"; byte[] bytes = md.digest(password.getBytes()); //md5加密后变成了数组的格式 String str = Base64.getEncoder().encodeToString(bytes);//通过Base64加密成字符串 System.out.println(str); //o4S2Rj/CFqX47LZnD4ZFag== } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } }
生成哈希值
public class T { public static void main(String[] args) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update("sss".getBytes()); // digest()最后确定返回md5 hash值,返回值为8位字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符 // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值 //一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方) String s = new BigInteger(1, md.digest()).toString(16); System.out.println(s); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } }
maven中依赖的一个jar包(具体不太清楚了)
DigestUtils.md5DigestAsHex("1111".getBytes())
jar包: http://maven.ibiblio.org/maven2/commons-codec/commons-codec/1.6/
System.out.println(DigestUtils.md5Hex("111".getBytes()))
lambda表达式:
用于回调方法:比如一个类方法的某些功能需要外部来自定义实现,我们调用类方法,就可以给传入自定义实现。
lambda表达式的实现:说明了java承认函数式编程
如果需求是定义了一个接口,需要创建该接口的实现类,重写接口的方法,而lambda可以简化了这种写法
lambda 不会生成class文件
接口只能有一个(抽象方法)-->函数式接口
Lambad表达式的优缺点:
优点:简单 对于并行计算非常有优势(底层使用的是fork/join来处理的)
缺点:不易调试,如果说不使用并行计算的话,速度没有for循环快
1.8之后默认方法可以加,静态方法可以添加
public class Demo { public static void main(String[] args) { //无参使用 Test t = ()->{System.out.println("嗨");}; t.eat(); //有参使用 String x 中String可以省略 Test2 t2 = (String x)->{System.out.println("我是"+x);}; t2.eat("小名"); //待返回值 Test3 t3 = ()->{ System.out.println("Test3"); return 10; }; t3.eat(); //可以简写,如果只有一句代码,就是返回值的话;直接简写即可,不能加return,如果加return必须加上{} Test3 t4 = ()->10; System.out.println(t4.eat()); } } interface Test{ public void eat();//只能有一个方法 } interface Test2{ public void eat(String x);//只能有一个方法 } interface Test3{ public int eat();//只能有一个方法 }
可以简单理解lanbda是简化匿名内部类的
Test a = new Test(){
public void test(){}
}
Test a = ()-->{} 必须有一个接口引用指向他
public void xx(Test t){} xx(()-->{})
public static void main(String[] args) throws IOException { ArrayList<String> strings = new ArrayList<>(); strings.add("1"); strings.add("2"); strings.forEach(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); //使用lambda表达式来简写方法体,(String s)->{System.out.println(s);}指向的是Consumer strings.forEach((String s)->{System.out.println(s);}); }
四大基础函数接口
函数接口,你可以理解为对一段行为的抽象,简单点说可以在方法就是将一段行为作为参数进行传递,这个行为呢,可以是一段代码,也可以是一个方法,那你可以想象在java8之前要将一段方法作为参数传递只能通过匿名内部类来实现,而且代码很难看,也很长,函数接口就是对匿名内部类的优化。
虽然类库中的基本函数接口特别多,但其实总体可以分成四类,就好像阿拉伯数字是无限多的,但总共就10个基本数字一样,理解了这4个,其他的就都明白了。
1、Customer接口
Consumer 接口翻译过来就是消费者,顾名思义,该接口对应的方法类型为接收一个参数,没有返回值,可以通俗的理解成将这个参数'消费掉了',一般来说使用Consumer接口往往伴随着一些期望状态的改变或者事件的发生,例如最典型的forEach就是使用的Consumer接口,虽然没有任何的返回值,但是却向控制台输出了语句。
示例1:
import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("7"); list.add("2"); list.add("3"); //list.forEach((String s)->{System.out.println(s);}); list.forEach(s->System.out.println(s));//简写 list.forEach(System.out::println); //另一个中写法,‘::’表示调用方法,此时的调用println方法,将s传进去 } }
示例2
public static void main(String[] args) { Consumer<String> printString = s -> System.out.println(s); printString.accept("helloWorld!"); //控制台输出 helloWorld! }
2、Function接口
Function<T,R>
Funtion接口是对接受一个T类型参数,返回R类型的结果的方法的抽象,通过调用apply方法执行内容。
示例1;
public class Test { public static void main(String[] args) { functiontest(); } public static void functiontest(){ String x = strToUpper("dfs", s->s.toUpperCase()); //{s.toUpperCase();}不能这样写 System.out.println(x); } public static String strToUpper(String str,Function<String, String> f){ return f.apply(str); } }
示例2
public class Operation{ /* 下面这个方法接受一个int类型参数a,返回a+1,符合我上面说的接受一个参数,返回一个值 所以呢这个方法就符合Function接口的定义,那要怎么用呢,继续看例子 */ public static final int addOne(int a){ return a+1; } /* 该方法第二个参数接受一个function类型的行为,然后调用apply,对a执行这段行为 */ public static int oper(int a, Function<Integer,Integer> action){ return action.apply(a); } /* 下面调用这个oper方法,将addOne方法作为参数传递 */ pulic static void main(String[] args){ int x = 1; int y = oper(x,x -> addOne(x));//这里可以换成方法引用的写法 int y = oper(x,Operation::addOne) System.out.printf("x= %d, y = %d", x, y); // 打印结果 x=1, y=2 /* 当然你也可以使用lambda表达式来表示这段行为,只要保证一个参数,一个返回值就能匹配 */ y = oper(x, x -> x + 3 ); // y = 4 y = oper(x, x -> x * 3 ); // y = 3 } }
Supplier接口
Supplier 接口翻译过来就是提供者,和上面的消费者相反,该接口对应的方法类型为不接受参数,但是提供一个返回值,通俗的理解为这种接口是无私的奉献者,不仅不要参数,还返回一个值,使用get()方法获得这个返回值
示例1:
import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; public class Test { public static void main(String[] args) { suppliertest(); } public static void suppliertest(){ List li = getNum(10, ()->(int)(Math.random()*100)); li.forEach(System.out::println); } public static List<Integer> getNum(int num,Supplier<Integer> sup){ List<Integer> list = new ArrayList<>(); for(int i=0;i<num;i++){ list.add(sup.get()); //表示执行了10次sup.get()方法 等于(int)(Math.random()*100) } return list; } }
示例2
Supplier<String> getInstance = () -> "HelloWorld!"; System.out.println(getInstance.get()); // 控偶值台输出 HelloWorld
Predicate接口
predicate<T,Boolean> 谓语接口,顾名思义,中文中的‘是’与‘不是’是中文语法的谓语,同样的该接口对应的方法为接收一个参数,返回一个Boolean类型值,多用于判断与过滤,当然你可以把他理解成特殊的Funcation<T,R>,但是为了便于区分语义,还是单独的划了一个接口,使用test()方法执行这段行为
示例1:
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class Test { public static void main(String[] args) { predicatetest(); } public static void predicatetest(){ //List<String> list = new ArrayList<>(); //list.add("dd"); //list.add("ddd"); //list.add("ff"); List<String> list = Arrays.asList("dd","ddd","ff"); List<String> result = filter(list, (s)->s.contains("d")); System.out.println(result); } public static List<String> filter(List<String> list,Predicate<String> p){ List<String> result = new ArrayList<>(); for(String s:list){ if(p.test(s)){ //测试是否符合要求; 需要有参数s result.add(s); } } return result; } }
示例2
public static void main(String[] args) { Predicate<Integer> predOdd = integer -> integer % 2 == 1; System.out.println(predOdd.test(5)); //控制台输出 true }
关于lambda的限制
Java8中的lambda表达式,并不是完全闭包,lambda表达式对值封闭,不对变量封闭。简单点来说就是局部变量在lambda表达式中如果要使用,必须是声明final类型或者是隐式的final例如
int num = 123; Consumer<Integer> print = () -> System.out.println(num);
就是可以的,虽然num没有被声明为final,但从整体来看,他和final类型的变量的表现是一致的,可如果是这样的代码
int num = 123; num ++; Consumer<Integer> print = () -> System.out.println(num);
则无法通过编译器,这就是对值封闭(也就是栈上的变量封闭)
如果上文中的num是实例变量或者是静态变量就没有这个限制。
看到这里,自然而然就会有疑问为什么会这样?或者说为什么要这么设计。理由有很多,例如函数的不变性,线程安全等等等,这里我给一个简单的说明
- 为什么局部变量会有限制而静态变量和全局变量就没有限制,因为局部变量是保存在栈上的,而众所周知,栈上的变量都隐式的表现了它们仅限于它们所在的线程,而静态变量与实例变量是保存在静态区与堆中的,而这两块区域是线程共享的,所以访问并没有问题。
- 现在我们假设如果lambda表达式可以局部变量的情况,实例变量存储在堆中,局部变量存储在栈上,而lambda表达式是在另外一个线程中使用的,那么在访问局部变量的时候,因为线程不共享,因此lambda可能会在分配该变量的线程将这个变量收回之后,去访问该变量。所以说,Java在访问自由局部变量时,实际上是在访问它的副本,而不是访问原始变量。如果局部变量仅仅赋值一次那就没有什么区别了。
- 严格保证这种限制会让你的代码变得无比安全,如果你学习或了解过一些经典的函数式语言的话,就会知道不变性的重要性,这也是为什么stream流可以十分方便的改成并行流的重要原因之一。
@FunctionalInterface函数式接口注解
1、该注解只能标记在”有且仅有一个抽象方法”的接口上。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承Java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
4、该注解不是必须的,如果一个接口符合”函数式接口”定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
// 正确的函数式接口 @FunctionalInterface public interface TestInterface { // 抽象方法 public void sub(); // java.lang.Object中的方法不是抽象方法 public boolean equals(Object var1); // default不是抽象方法 public default void defaultMethod(){ } // static不是抽象方法 public static void staticMethod(){ } }
RandomAccessFile:
只可以对文件进行操作,当模式为r,文件不存在会报错,当模式为rw,文件不存在会自动创建文件,文件存在不会覆盖原文件;
对文件进行写入操作是,必须有r模式,只有先有读的权限,才能有写的权限(rw)
示例:复制文件
import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; public class Demo { public static void main(String[] args) throws IOException{ run(); } public static void run(){ try { RandomAccessFile rf = new RandomAccessFile("C:\\Users\\zhengyan\\Desktop\\test1\\all.jpg", "r"); RandomAccessFile wf = new RandomAccessFile("C:\\Users\\zhengyan\\Desktop\\test1\\new_all.jpg", "rw"); byte bytes[] = new byte[1024]; int len=-1; while((len=rf.read(bytes))!=-1){ wf.write(bytes,0,len); } System.out.println("复制成功"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
Properties:
使用环境:当代码已经上传的服务器后,如果需要对参数进行修改,而不需要对源代码重新编译,就会利用到配置文件,对配置文件进行修改,是不需要对源代码重新编译的
源代码--->编译(.class文件)--->打包上传到服务器
1、创建config.properties配置文件
username=admin password=123
2、代码
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Properties; public class Demo { private static String username; private static String password; public static void main(String[] args) throws IOException{ readConfig(); System.out.println(Demo.username); System.out.println(Demo.password); writeConfig("小明", "123456");//对配置文件写入操作 readConfig(); System.out.println(Demo.username); System.out.println(Demo.password); } public static void readConfig(){ Properties p = new Properties(); try { //InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com\\zy\\config.properties"); //是有问题的 InputStream inStream = new FileInputStream("src\\com\\zy\\config.properties"); p.load(inStream); username = p.getProperty("username"); password = p.getProperty("password"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void writeConfig(String username,String password){ Properties p = new Properties(); p.put("username", username); p.put("password", password); try { OutputStream out = new FileOutputStream("src\\com\\zy\\config.properties"); p.store(out, "updata config"); //updata config是描述信息 out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
StringUtils:
需要引入这个jar包
isBlank:“ ”:false
isEmpty:“ ” :true
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency>
BCryptPasswordEncoder:
比md5加密更加安全,采取随机加密
@Test public void testPasswrodEncoder(){ //原始密码 String password = "111111"; BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); //使用BCrypt加密,每次加密使用一个随机盐 for(int i=0;i<10;i++){ String encode = bCryptPasswordEncoder.encode(password); System.out.println(encode); //校验 boolean matches = bCryptPasswordEncoder.matches(password, encode); System.out.println(matches); } }
Map和Bean相互转换:
方式1:
package com.ihrm.common.utils; import org.springframework.cglib.beans.BeanMap; import java.util.HashMap; import java.util.Map; public class BeanMapUtils { /** * 将对象属性转化为map结合 */ public static <T> Map<String, Object> beanToMap(T bean) { Map<String, Object> map = new HashMap<>(); if (bean != null) { BeanMap beanMap = BeanMap.create(bean); for (Object key : beanMap.keySet()) { map.put(key+"", beanMap.get(key)); } } return map; } /** * 将map集合中的数据转化为指定对象的同名属性中 */ public static <T> T mapToBean(Map<String, Object> map,Class<T> clazz) throws Exception { T bean = clazz.newInstance(); BeanMap beanMap = BeanMap.create(bean); beanMap.putAll(map); return bean; } }
方式2:通过反射
//把JavaBean转化为map public static Map<String,Object> bean2map(Object bean) throws Exception{ Map<String,Object> map = new HashMap<>(); //获取JavaBean的描述器 BeanInfo b = Introspector.getBeanInfo(bean.getClass(),Object.class); //获取属性描述器 PropertyDescriptor[] pds = b.getPropertyDescriptors(); //对属性迭代 for (PropertyDescriptor pd : pds) { //属性名称 String propertyName = pd.getName(); //属性值,用getter方法获取 Method m = pd.getReadMethod(); Object properValue = m.invoke(bean);//用对象执行getter方法获得属性值 //把属性名-属性值 存到Map中 map.put(propertyName, properValue); } return map; } //把Map转化为JavaBean public static <T> T map2bean(Map<String,Object> map,Class<T> clz) throws Exception{ //创建一个需要转换为的类型的对象 T obj = clz.newInstance(); //从Map中获取和属性名称一样的值,把值设置给对象(setter方法) //得到属性的描述器 BeanInfo b = Introspector.getBeanInfo(clz,Object.class); PropertyDescriptor[] pds = b.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { //得到属性的setter方法 Method setter = pd.getWriteMethod(); //得到key名字和属性名字相同的value设置给属性 setter.invoke(obj, map.get(pd.getName())); } return obj; }