直接赋值:java推荐使用java
String name = "xiaoyu";//对象生成在常量池中
经过关键字new调用String的构造方法赋值正则表达式
String name = new String("xiaoyu");//建立了两个对象 new:表示申请内存空间
String表示一个字符串,内部使用字符数组实现,不能被继承(它是最终类),不可变算法
package com.API.demo01; public class Demo01{ public static void main(String[] args) { //直接赋值字符串链接时,考虑编译器和运行期 //若是在编译器值能够被肯定,那么使用已有的对象,不然会建立新的对象 String a = "a"; String a1 = a+1;//在堆中建立一个“a1” String a2 = "a1";//这个a1是在常量池中 System.out.println(a1==a2);//false final String b = "b";//final是常量 String b1=b+1;//常量相加 String b2="b1"; System.out.println(b1==b2);//true String c = getC(); String c1=c+1; String c2="c1"; System.out.println(c1==c2);//false final String d = getD(); String d1=d+1; String d2="d1"; System.out.println(d1==d2);//false } private static String getC(){ return "c"; } private static String getD(){ return "d"; } }
构造一个空字符串对象编程
String s = new String();
经过byte数组构造字符串对象数组
经过byte数组,从offset开始,总共length长的字节构造字符串对象安全
经过char数组构造字符串对象多线程
char[] cs ={'a','b','c'}; String s1 = new String(cs);//将数组变成字符串
经过char数组,从offset开始,总共length长的字节构造字符串对象app
char[] cs ={'a','b','c'}; String s2 = new String(cs,0,2); System.out.println(s2);//a
判断是否为空,指的是内容为空dom
String str1=""; System.out.println(str1.isEmpty());//true
查看字符串长度ide
String str = "sads1231sad"; System.out.println(str.length());//11
String str = "sads1231sad"; System.out.println(str.toUpperCase());//SADS1231SAD
String str1= "WEDVCSDFZZVC"; System.out.println(str1.toLowerCase());//wedvcsdfzzvc
用户数据后台校验前的过滤,返回字符串的副本,忽略前部空白和尾部空白
String str1= " WEDVCS DFZZVC "; System.out.println(str1.trim());//WEDVCS DFZZVC
字符号链接操做
String str = "sads1231sad"; System.out.println(str.concat("***8*"));//sads1231sad***8*
获取字符串中的某个值
String str = "sads1231sad"; char c=str.charAt(1); System.out.println(c);//a
判断一个字符串是否包含另外一个字符串
String str = "sads1231sad"; System.out.println(str.contains("a"));//true
String str = "sads1231sad"; System.out.println(Arrays.toString(str.getBytes()));//[115, 97, 100, 115, 49, 50, 51, 49, 115, 97, 100]
String str = "sads1231sad"; System.out.println(str.toCharArray());//sads1231sad
比较两个字符串的大小,相等返回0,大于返回正数,小于返回负数
String str = "sads1231sad"; String str1= "WEDVCSDFZZVC"; System.out.println(str.compareTo(str1));//28
比较两个字符串的大小,不考虑大小写
String str = "sads1231sad"; String str1 = "SADS1231SAD" System.out.println(str.compareToIgnoreCase(str1));//0
从头查找指定字符是否存在,char→int,若是存在则返回第一个出现的位置,若是不存在则返回-1 ch是阿斯克码
String str = "sads1231sad"; System.out.println(str.indexOf(97));//1
从头指定位置查找指定的字符是否存在,char→int,若是存在则返回位置,若是不存在则返回-1
String str = "sads1231sad"; System.out.println(str.indexOf(97,2));//9
从头查找指定字符串是否存在,若是存在则返回第一个出现的位置,若是不存在则返回-1
String str = "sads1231sad"; System.out.println(str.indexOf("a"));//1
从头指定位置查找字符串是否存在,若是存在则返回位置,若是不存在则返回-1
String str = "sads1231sad"; System.out.println(str.indexOf("a",2));//9
从后查找指定字符串是否存在,若是存在则返回第一个出现的位置,若是不存在则返回-1
String str = "sads1231sad"; System.out.println(str.lastIndexOf("a"));//9
从第一个位置开始判断是否以指定的内容开头
String str = "sads1231sad"; System.out.println(str.startsWith("s"));//true
从指定的位置开始判断是否以指定的内容开头
String str = "sads1231sad"; System.out.println(str.startsWith("s",4));//false
判断是否以指定的内容结尾 能够用于判断文件以什么格式结束
String str = "sads1231sad"; System.out.println(str.endsWith("d"));//true
String str = "sads1231sad"; System.out.println(str.replace('s','*'));//*ad*1231*ad
String str = "sads1231sad"; System.out.println(str.replace("12","DD"));//sadsDD31sad
regex是正则表达式的意思
String str = "sads1231sad"; System.out.println(str.replaceAll("[0-9]","*"));//sads****sad //System.out.println(str.replaceAll("\\d","*"));//sads****sad
替换第一个知足条件的字符串
String str = "sads1231sad"; System.out.println(str.replaceFirst("[0-9]","*"));//sads*231sad
从指定位置开始一直截取到末尾
String str = "sads1231sad"; System.out.println(str.substring(4));//1231sad
截取指定范围的字符串
String str = "sads1231sad"; System.out.println(str.substring(0,4));//sads
根据给定正则表达式的匹配拆分此字符串。
String str = "sads1231sad"; System.out.println(Arrays.toString(str.split("s")));//[, ad, 1231, ad]
根据给定正则表达式的匹配拆分此字符串,并指定拆分的个数。
String str = "sads1231sad"; System.out.println(Arrays.toString(str.split("1",2)));//[sads, 231sad]
把各类类型转换成字符串
System.out.println(String.valueOf(true));//true
在实际开发当中,咱们常常会使用到字符串链接的操做,若是String来操做,则使用"+"号完成字符串的链接操做
使用String链接字符串,代码性能会很是低,由于String的内容不可改变,解决这个问题的方法是使用StringBuffer
package com.API.demo01; public class Demo03 { public static void main(String[] args) { String a = "a"; String b = "b"; String c = a+b+1;//变量和常量相加产生三个对象 String d = "a"+"b"+1;//常量相加产生1个对象 没有性能问题,由于在编译器就进行了优化 //System.out.println(c);//ab1 产生五个对象 //StringBuffer目的是来解决字符串相加时带来的性能问题(常量与变量相加) //StringBuffer的内部实现采用字符数组,默认数组的长度为16,超过数组大小时,动态扩充的算法是原来长度*2+2 //因此当咱们预知要添加的数据长度时,建议使用带初始化容量的构造方法,来避免动态扩充的次数,从而提升效率 //线程安全的,会影响性能 StringBuffer sb = new StringBuffer(); sb.append(a).append(b).append(1); System.out.println(sb.toString());//ab1 产生一个对象 } }
构造一个空的StringBuffer对象
StringBuffer s = new StringBuffer(); StringBuffer s1 = new StringBuffer(32);//带容量的构造(推荐)
将制定的String变为StringBuffer的内容
StringBuffer s = new StringBuffer("ABC");
接收CharSequence接口的实例
提供了不少append()方法,用于进行字符串链接
删除指定位置的内容
StringBuffer s = new StringBuffer("ABC"); System.out.println(s.delete(0,1));//BC
字符串的查询功能
在指定位置上增长一个内容
StringBuffer s = new StringBuffer("ABC"); System.out.println(s.insert(1,"f"));//AfBC
将指定范围的内容替换成其余内容
截取指定范围的字符串
字符串截取
字符串反转
StringBuffer s = new StringBuffer("ABC"); System.out.println(s.reverse());//CBA
一个可变的字符序列。此类提同一个与StringBuffer兼容的API,但不保证同步。该类被设计用做StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。若是可能,建议先采用该类,由于在大多数实现中,它比StringBuffer要快
public class Demo04 { public static void main(String[] args) { //StringBuffery与StringBuilder的区别? //StringBuffer是线程安全的,性能低,适合在多线程中使用,JDK1.0 //StringBuilder是线程不安全的,性能高,适合在单线程中使用,这种状况占大多数,在JDK1.5后使用 StringBuilder s = new StringBuilder(); //字符串相加操做 //1.多个常量相加没有性能问题 //2.变量与常量相加,会产生多个垃圾对象、 String a = "a"+1; //字符串相加,在编译后,会使用StringBuilder相优化代码,实现拼接 } }
Locale对象表示特定的地理、政治和文化地区。须要locale来执行其任务的操做称为语言环境敏感的操做,它使用Locale为用户量身定制信息。例如,显示一个数值就是语言环境敏感的操做,应该根据用户的国家、地区或文化的风俗/传统来格式化该数值
Locale(String language)
Locale(String language,String country)
经过静态方法建立Locale:getDefault()
package com.API.demo02; import java.util.Locale; public class I18Demo { public static void main(String[] args) { //建立一个本地语言环境对象,该对象会根据参数设置来自动选择与之相关的语言环境 //参数:语言,地区 Locale locale_CN = new Locale("zh","CN"); Locale locale_US = new Locale("en","US"); //获取当前系统默认的语言环境 Locale locale_default = Locale.getDefault(); } }
国际化的实现核心在于显示的语言上,一般的作法是将其定义成若干个属性文件(文件后缀是*.properties),属性文件中的格式采用“key=value”的格式来进行操做。Properties文件:属性文件(配置文件),内容以键值对的形式存放(key-value)
ResourceBundle类表示的是一个资源文件的读取操做,全部的资源文件须要使用ResourceBundle进行读取,读取的时候不须要加上文件的后缀。ResourceBundle工具类,来绑定属性文件,并指定Locale对象,来自动选择使用哪一个属性文件,默认将使用与操做系统相同的语言环境
package com.API.demo02; import java.util.Locale; import java.util.ResourceBundle; import java.util.Scanner; public class I18Demo { public static void main(String[] args) { //建立一个本地语言环境对象,该对象会根据参数设置来自动选择与之相关的语言环境 //参数:语言,地区 Locale locale_CN = new Locale("zh","CN"); Locale locale_US = new Locale("en","US"); //获取当前系统默认的语言环境 Locale locale_default = Locale.getDefault(); Scanner input = new Scanner(System.in); //用于绑定属性文件的工具类(参数:属性文件的基本名,就是前缀) ResourceBundle r = ResourceBundle.getBundle("com.API.demo02.info",locale_CN);//中文 //ResourceBundle r = ResourceBundle.getBundle("com.API.demo02.info",locale_US);英文 System.out.println(r.getString("system.name")); System.out.println(r.getString("input.username")); String username = input.nextLine(); System.out.println(r.getString("input.password")); String password = input.nextLine(); if("admin".equals(username) && "123".equals(password)){ System.out.println(r.getString("login.success")); }else{ System.out.println(r.getString("login.error")); } } }
结果:中文
英文
用于绑定属性文件的工具类(参数:属性文件的基本名(就是前缀))
getBundle(String baseName,Locale locale)
从属性文件中使用key来获取value
注:ResourceBundle工具类是只读的
用来处理动态文本
package com.API.demo02; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; import java.util.Scanner; public class I18Demo { public static void main(String[] args) { //建立一个本地语言环境对象,该对象会根据参数设置来自动选择与之相关的语言环境 //参数:语言,地区 Locale locale_CN = new Locale("zh","CN"); Locale locale_US = new Locale("en","US"); //获取当前系统默认的语言环境 Locale locale_default = Locale.getDefault(); Scanner input = new Scanner(System.in); //用于绑定属性文件的工具类(参数:属性文件的基本名,就是前缀) ResourceBundle r = ResourceBundle.getBundle("com.API.demo02.info",locale_CN); System.out.println(r.getString("system.name")); System.out.println(r.getString("input.username")); String username = input.nextLine(); System.out.println(r.getString("input.password")); String password = input.nextLine(); if("admin".equals(username) && "123".equals(password)){ System.out.println(r.getString("login.success")); String welcome = r.getString("welcome"); //动态文本格式化 welcome =MessageFormat.format(welcome,username); System.out.println(welcome); }else{ System.out.println(r.getString("login.error")); String sorry = r.getString("sorry"); //动态文本格式化 sorry =MessageFormat.format(sorry,username); System.out.println(sorry); } } }
结果:
Math类包含用于执行的基本数学运算方法,如初等指数、对数、平方根和三角函数。
使用Math类能够有两种方式:
比任何其余值都更接近pi的double值
System.out.println(Math.PI);//3.141592653589793
返回double值的绝对值
System.out.println(Math.abs(-10));//10
返回带正号的double值,该值大于等于0.0且小于1.0
System.out.println(Math.random());//随机0-1之间的小数
返回最接近参数并等于某一整数的double值
System.out.println(Math.round(Math.random()*10));//5 随机数扩大十倍再取整 System.out.println(Math.round(Math.random()*100)/100.0);//0.92随机数保留两位小数
返回正确舍入的double值的正平方根
System.out.println(Math.sqrt(2));//1.4142135623730951
返回一个四舍五入的近似值
package com.API.demo03; import static java.lang.Math.floor; public class MathDemo { public static void main(String[] args) { System.out.println(floor(1.23235341));//1.0 } }
此类的实例用于生成伪随机数流
返回下一个伪随机数的long值
package com.API.demo03; import java.util.Random; public class MathRandomDemo { public static void main(String[] args) { Random r = new Random(); System.out.println(r.nextLong());//-2965780218345956466 } }
返回下一个伪随机数的boolean值
返回下一个伪随机数,在0.0和1.0之间的double值
返回下一个伪随机数,int值
返回一个伪随机数,在0(包括)和指定值分布的int值
Random r = new Random(); System.out.println(r.nextInt(20));//11 随机20之内的整数
表示特定的瞬间,精确到毫秒,也就是程序运行时的当前时间
Date date = new Date();//实例化Date对象,表示当前时间
分配Date对象并初始化此对象,以表示分配它的时间
import java.util.Date; public class DateDemo { public static void main(String[] args) { Date date = new Date(); System.out.println(date);//Wed May 27 22:43:36 CST 2020 } }
分配一个毫秒来获取时间 参数是毫秒
import java.util.Date; public class DateDemo { public static void main(String[] args) { Date d1 = new Date(520000); System.out.println(d1);//Thu Jan 01 08:08:40 CST 1970 } }
日历类,使用此类能够将时间精确到毫秒显示
两种实例化方式:
package com.API.demo04; import java.util.Calendar; import java.util.GregorianCalendar; public class DateDemo { public static void main(String[] args) { Calendar c1 = Calendar.getInstance(); Calendar c2 = new GregorianCalendar(); int year = c1.get(Calendar.YEAR); int month = c1.get(Calendar.MONTH); int day = c1.get(Calendar.DAY_OF_MONTH); int hour = c1.get(Calendar.HOUR_OF_DAY); int minute = c1.get(Calendar.MINUTE); int second = c1.get(Calendar.SECOND); int millisecond = c1.get(Calendar.MILLISECOND); StringBuilder sb = new StringBuilder(50); sb.append(year).append("年").append(month).append("月").append(day).append("日") .append(hour).append(":").append(minute) .append(":").append(second).append(" ").append(millisecond); System.out.println(sb.toString());//2020年4月27日23:7:7 361 } }
package com.API.demo04; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; public class DateDemo { public static void main(String[] args) { DateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS"); String nowDate = df.format(new Date()); System.out.println(nowDate);//2020年05月27日 23:13:36 809 } }
对两个或多个数据项进行比较,以肯定它们是否相等,或肯定它们之间的大小关系及排列顺序称为比较。
前面咱们学习的Arrays.sorts方法能够实现对象的排序操做
此接口强行对实现它的每一个类的对象进行总体排序。这种排序被称为类的天然排序,类的compareTo方法被称为它的天然比较方法。
测试类:
package com.API.demo05; import java.util.Arrays; public class ComDemo { public static void main(String[] args) { Cat[] cats = {new Cat("鱼鱼",1),new Cat("付付",4),new Cat("tom",2)}; Arrays.sort(cats); System.out.println(Arrays.toString(cats));//[Cat{name='鱼鱼', age=1}, Cat{name='tom', age=2}, Cat{name='付付', age=4}] }
Cat类:
package com.API.demo05; //<>里写的是比较对象 public class Cat implements Comparable<Cat>{ private String name; private int age; public Cat() { } public Cat(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Cat{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int compareTo(Cat o) { //if(this.age<o.age)return -1; //if(this.age>o.age)return 1; //return 0; return this.age-o.age; } }
Comparable接口是要求自定义类去实现,按照OO原则:对修改关闭,对扩展开放。(在类里直接加接口)
Comparator接口是强行对某个对象collection进行总体排序的比较。(新建一个接口类)
测试类:
package com.API.demo05; import java.util.Arrays; public class ComDemo { public static void main(String[] args) { Dog[] dogs = {new Dog("鱼鱼",1),new Dog("付付",4),new Dog("tom",2)}; Arrays.sort(dogs,new DogComparator());//选择比较器 System.out.println(Arrays.toString(dogs));//[Dog{names='鱼鱼', age=1}, Dog{names='tom', age=2}, Dog{names='付付', age=4}] } }
在Dog类里若是没有toString方法则输出结果,会变成[com.API.demo05.Dog@1b6d3586, com.API.demo05.Dog@4554617c, com.API.demo05.Dog@74a14482],就和直接System.out.println()数组不能直接输出数组必须借助Arrays.toString()一个道理。
Dog类:
package com.API.demo05; public class Dog { private String names; private int age; public Dog() { super(); } public Dog(String names, int age) { this.names = names; this.age = age; } public String getNames() { return names; } public void setNames(String names) { this.names = names; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override//若是没有这个就会出现乱码 public String toString() { return "Dog{" + "names='" + names + '\'' + ", age=" + age + '}'; } }
接口类DogComparator:
package com.API.demo05; import java.util.Comparator; public class DogComparator implements Comparator<Dog> { @Override public int compare(Dog o1, Dog o2) { return o1.getAge()-o2.getAge(); } }
若是某个类的对象要想被克隆,则对象所在的类必须实现Cloneable接口。此接口没有定义任何方法,是一个标记接口
测试类:
package com.API.Demo06; public class Test { public static void main(String[] args) { Cat cat = new Cat("付付",2); try { Cat newCat = (Cat) cat.clone(); System.out.println("cat="+cat);//cat=Cat{name='付付', age=2} System.out.println("new cat="+newCat);//new cat=Cat{name='付付', age=2}地址不同 System.out.println(cat==newCat);//false } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
Cat类:
package com.API.Demo06; /** * 对象须要具有克隆功能: * 1.实现Cloneable接口(标记接口) * 2.重写Object类中的Clone方法 * @Author 油炸蘑菇鱼 */ public class Cat implements Cloneable{ private String name; private int age; public Cat() { } @Override public String toString() { return "Cat{" + "name='" + name + '\'' + ", age=" + age + '}'; } public Cat(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //重写Object中的clone方法 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
System.out.println("向控制台输出");//向控制台输出 System.err.println("出错啦");//出错啦(红色字体)
该方法是数组拷贝,也就是将一个数组中的内容复制到另一个数组的指定位置,因为该方法是native本地方法,因此性能上比使用循环高效
int[] num1 = {1,2,3,4,5,6,7,8}; int[] num2 = new int[num1.length]; //参数(原数组,原数组的起始位置,目标数组,目标数组的起始位置,长度) System.arraycopy(num1,0,num2,0,num1.length); System.out.println(Arrays.toString(num2));//[1, 2, 3, 4, 5, 6, 7, 8]
该方法的做用是返回当前的计算机的时间,时间的表达式为当前计算机时间和GMT时间(格林威治时间)1970年1月1日0时0分0秒所差的毫秒差
System.out.println(System.currentTimeMillis());//1592743150979 Date nowDate = new Date(System.currentTimeMillis()); DateFormat DF = new SimpleDateFormat("HH:MM:SS"); String now = DF.format(nowDate); System.out.println(now);//20:06:523
该方法做用是退出程序。其中status的值为0表示正常退出,非零表明异常退出。使用该方法能够在图形界面编程中实现程序的退出功能等
System.exit(0);//退出JVM
该方法的做用是请求系统进行垃圾回收。至于系统是否马上回收,则取决于系统中垃圾回收算法的实现以及系统执行时的状况
该方法的做用是得到系统中属性名为key的属性对应的值
System.out.println(System.getProperty("java.version"));//1.8.0_251 System.out.println(System.getProperty("java.home"));//C:\Program Files\Java\xxxxxxx System.out.println(System.getProperty("os.name"));//Windows 10 System.out.println(System.getProperty("user.name"));//10260 System.out.println(System.getProperty("os.version"));//10.0
用于加载第三方类库,例如加载C,C++编写的类库
每一个java应用程序都有一个Runtime类实例,使应用程序可以与其运行环境相链接
Runtime rt = Runtime.getRuntime(); System.out.println("处理器数量:"+rt.availableProcessors());//处理器数量:4 System.out.println("JVM总内存数:"+rt.totalMemory()+"byte");//JVM总内存数:124780544byte System.out.println("JVM空闲内存数:"+rt.freeMemory()+"byte");//JVM空闲内存数:120840808byte System.out.println("JVM可用最大内存数:"+rt.maxMemory()+"byte");//JVM可用最大内存数:1836580864byte //在单独的进程中执行指定的字符串命令 try { rt.exec("notepad");//打开笔记本 } catch (IOException e) { e.printStackTrace(); }
可让超出integer范围内的数据进行运算
//大整数运算 String val1="122313142342342"; String val2="858938563422344"; BigInteger b1 = new BigInteger(val1); BigInteger b2 = new BigInteger(val2);
加
System.out.println(b1.add(b2));//981251705764686
减
System.out.println(b1.subtract(b2));//-736625421080002
乘
System.out.println(b1.multiply(b2));//105059474771203913323980089648
除
System.out.println(b1.divide(b2));//0
取模
System.out.println(b1.remainder(b2));//122313142342342
除加取余
System.out.println(Arrays.toString(b1.divideAndRemainder(b2)));//[0, 122313142342342]
用于运算的时候,float类型和double类型很容易丢失精度,为了能精确的表示、计算浮点数,java提供了BigDecimal,不可变的、任意精度的有符号十进制数
String val3 = "5679.97979080728929"; String val4 = "398.2192381964231419129"; BigDecimal b3 = new BigDecimal(val3); BigDecimal b4 = new BigDecimal(val4);
System.out.println(b3.add(b4));//6078.1990290037124319129
System.out.println(b3.subtract(b4));//5281.7605526108661480871
System.out.println(b3.multiply(b4));//2261877.225266357622421505259065434282841
System.out.println(b3.divide(b4));//出错
用于小数处理的问题
double pi = 3.14159265358; //取一位整数 System.out.println(new DecimalFormat("0").format(pi));//3 //取一位整数和两位小数 System.out.println(new DecimalFormat("0.00").format(pi));//3.14 //取两位整数和三位小数 System.out.println(new DecimalFormat("00.000").format(pi));//03.142 //取全部整数部分 System.out.println(new DecimalFormat("#").format(pi));//3 //以百分比方式计数 System.out.println(new DecimalFormat("#.##%").format(pi));//314.16% long num = 683892097; System.out.println(new DecimalFormat("###,###").format(num));//683,892,097
Message-Digest Algorithm 5 (信息摘要算法)
关于密码存储
package com.API.Demo09; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Base64; public class MDA5Demo { private static String savePassword = "pmq7VoTEWWLYh1ZPCDRujQ==";//存储的密文 public static void main(String[] args) { //test(); System.out.println(login("admin112ss"));//false System.out.println(login("admin123456"));//true } private static boolean login(String password){ if(savePassword.equals(md5(password))){ return true; }else{ return false; } } //计算md5的工具方法 private static String md5(String password){ try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] bytes = md.digest(password.getBytes("UTF-8"));//经过MD5计算摘要 String str = Base64.getEncoder().encodeToString(bytes); return str; } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { e.printStackTrace(); } return null; } private static void test() { String password = "admin123456";//原文 String savePassword = "pmq7VoTEWWLYh1ZPCDRujQ==";//存储的密文 try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] bytes = md.digest(password.getBytes("UTF-8"));//经过MD5计算摘要 System.out.println(Arrays.toString(bytes));//[-90, 106, -69, 86, -124, -60, 89, 98, -40, -121, 86, 79, 8, 52, 110, -115] //String mdStr = new String(bytes); //System.out.println(mdStr);//�j�V��Yb؇V4n� //a-z A-Z 0-9 / * BASE64编码算法 String str = Base64.getEncoder().encodeToString(bytes);//编码 System.out.println(str);//pmq7VoTEWWLYh1ZPCDRujQ== byte[] bs = Base64.getDecoder().decode(str);//解码 System.out.println(Arrays.toString(bs));//[-90, 106, -69, 86, -124, -60, 89, 98, -40, -121, 86, 79, 8, 52, 110, -115] } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { e.printStackTrace(); } } }