1、 字符串操作——String类
1、 String可以表示一个字符串。
2、 String类实际是使用字符数组存储的。
String类的两种赋值方式:
- 一种称为直接赋值:String name = “小白”
- 通过关键字new调用String的构造方法赋值:String name = new String(“小白”)
String类的两种赋值分析:
- 字符串常量池
- String name = new String(“小白”), 在内存中的分析
- String name = “小白”, 在内存中的分析
String类编译期与运行期分析:
- 编译期和运行期
- 代码示例: 4种情况分析
package com.vince;/**** @author vince* @description* String 表示一个字符串,内部使用字符数组实现,不能被继承(最终类),不可变*/public class StringDemo {public static void main(String[] args) {//String 的两种赋值方式,JAVA推荐使用第一种方式//1 直接赋值String s1 = "你好"; //此时“你好”放在字符串常量池中//2 使用new关键字创建对象,new:表示申请内存空间////面试题 问以下代码创建了几个对象? 2个String s2 = new String("你好");String s3 = "你好"; //直接在常量池中寻找,省内存空间System.out.println(s1==s2);//falseSystem.out.println(s1==s3);//trueSystem.out.println("-----------------");//代码示例:4种情况分析:直接赋值字符串连接时,考虑编译期和运行期//如果在编译期值 可以被确定,那么就使用已有的对象,否则会创建新的对象String a = "a";String a1 = a+1;String a2 = "a1";System.out.println(a1==a2);//falsefinal String b = "b"; //b此时是常量String b1 = b+1; //在编译器b1可以被确定String b2 = "b1";System.out.println(b1==b2);//trueString c = getC();String c1 = c+1;String c2 = "c1";System.out.println(c1==c2);//falsefinal 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";}}
(1)字符与字符串操作方法


(2)判断是否以指定内容开头或结尾

(3)替换操作

(4)字符串截取操作

(5)字符串拆分操作

(6)字符串查找操作


(7)其它操作方法

import java.util.Arrays;public class StringDemo2 {public static void main(String[] args) {String str = " fkwefwfa d6737383 ";char c = str.charAt(1);System.out.println(c); //fSystem.out.println(str.toCharArray()); // fkwefwfa d6737383char[] cs = {'a','b','c'};String s1 = new String(cs);System.out.println(s1); //abcString s2 = new String(cs,0,1);System.out.println(s2); //aSystem.out.println(Arrays.toString(str.getBytes()));//[32, 102, 107, 119, 101, 102, 119, 102, 97, 32, 100, 54, 55, 51, 55, 51, 56, 51, 32]System.out.println(str.replace('w', '*')); // fk*ef*fa d6737383System.out.println(str.replaceAll("\\d", "*")); // fkwefwfa d*******System.out.println(str.substring(0, 4)); //fkwSystem.out.println(Arrays.toString(str.split("d"))); //[ fkwefwfa , 6737383 ]System.out.println(str.contains("a")); //trueSystem.out.println(str.indexOf("f")); //1System.out.println(str.lastIndexOf("f")); //7System.out.println(str.isEmpty()); //falseSystem.out.println(str.length()); //19System.out.println(str.trim()); //fkwefwfa d6737383System.out.println(str.concat("*****")); // fkwefwfa d6737383 *****System.out.println(String.valueOf(10)); //10}}
2、字符串操作——StringBuffer类
在实际开发当中, 我们经常会使用到字符串连接的操作, 如果用String来操作, 则使用“ +” 号完成字符串的连接操作。
使用String连接字符串, 代码性能会非常低, 因为String的内容不可改变。
解决这个问题的方法是使用StringBuffer。
StringBuffer常用操作方法

public class StringBufferDemo {public static void main(String[] args) {String a = "a";String b = "b";String c = a+b+1; //会出现5个对象System.out.println(c);String d = "a"+1+2+3+4+"b";//a1234b //常量相加没有性能问题(编译期进行优化)//StringBuffer目的是来解决字符串相加时带来的性能问题(常量与变量)//StringBuffer的内部实现采用字符数组,默认数组的长度为16,超过数组大小时,动态扩充的算法是原来长度*2+2//所以当我们预知要添加的数据长度时,建议使用带初始化容量的构造方法,来避免动态扩充的次数,从而提高效率//带线程锁,故线程安全的,但会影响性能,StringBuffer sb = new StringBuffer(32);//带容量的构造(建议)sb.append(a).append(b).append(1);System.out.println(sb.toString());StringBuffer sb2 = new StringBuffer("abc");sb2.delete(0, 1);System.out.println(sb2); //bc}}
3、字符串操作——StringBuilder类
StringBuffer的兄弟StringBuilder:
一个可变的字符序列。 此类提供一个与 StringBuffer 兼容的 API, 但不保证同步。 该类被设计用作 StringBuffer 的一个简易替换, 用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。
如果可能, 建议优先采用该类, 因为在大多数实现中, 它比StringBuffer 要快。
JDK1.5以后, 字符串相加原理分析
public class StringBuilderDemo {public static void main(String[] args) {//面试题 :StringBuffer与StringBuilder的区别?//StringBuffer是线程安全的,性能低,适合在多线程的使用,JDK1.0//StringBuilder是线程不安全的,性能高,适合在单线程中使用,这种情况占多大数,在jdk1.5后添加//StringBuilder sb = new StringBuilder();//字符串相加操作//1、多个常量相加没有性能问题 ,在编译期优化//2、变量与常量相加,会产生多个垃圾对象//String a = "a"+1;//String b = a+"b";String c = null;for(int i=0;i<5;i++){c+=i; //每次循环会产生一个StringBuilder对象实现拼接,性能低,最好是手动创建StringBuilder来拼接}//1、字符串相加,在编译后,会使用StringBuilder来优化代码,实现拼接}StringBuilder sb3=new StringBuilder();sb3.append(1).append(2).append(3);System.out.println(sb3);}
4、程序国际化
(1) 对国际化程序的理解
Internationalization: 国际化程序可以这样理解:
同一套程序代码可以在各个语言环境下进行使用。
各个语言环境下, 只是语言显示的不同, 那么具体的程序操作本身都是一样的, 那么国际化程序完成的就是这样的一个功能。
(2)Locale类
Locale 对象表示了特定的地理、 政治和文化地区。 需要 Locale 来执行其任务的操作称为语言环境敏感的操作, 它使用 Locale 为用户量身定制信息。 例如, 显示一个数值就是语言环境敏感的操作, 应该根据用户的国家、 地区或文化的风俗/传统来格式化该数值。
使用此类中的构造方法来创建 Locale:
Locale(String language)Locale(String language, String country)
通过静态方法创建Locale:
getDefault()
(3)ResourceBundle类
国际化的实现核心在于显示的语言上, 通常的做法是将其定义成若干个属性文件(文件后缀是*.properties) , 属性文件中的格式采用“ key=value” 的格式进行操作。
ResourceBundle类表示的是一个资源文件的读取操作, 所有的资源文件需要使用ResourceBundle进行读取, 读取的时候不需要加上文件的后缀。
getBundle(String baseName)getBundle(String baseName,Locale locale)getString(String key)
(4)处理动态文本
前面的示例读取的内容都是固定的, 如果现在假设要想打印这样的信息“ 欢迎你,XXX! ” , 具体的名字不是固定的, 那么就要使用动态文本进行程序的处理。
进行动态的文本处理, 必须使用java.text.MessageFormat类完成。 这个类是java.text.Format的子类。
package com.vince;import java.text.MessageFormat;import java.util.Locale;import java.util.ResourceBundle;import java.util.Scanner;/*** 程序国际化* 1、Locale* 2、Properties文件:属性文件(配置文件),内容以键值对的形式存放(key-value)* 3、ResourceBundle工具类,来绑定属性文件,并指定Locale对象,来自动选择使用哪个属性文件,默认将使用与操作系统相同的语言环境。* getString()方法来从属性文件中使用key来获取value* 注意,ResourceBundle工具类是只读的*/public class I18NDemo {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);//用于绑定属性文件的工具类(参数:属性文件的基本名(就是前缀,比如,info))//ResourceBundle 工具类ResourceBundle r = ResourceBundle.getBundle("com.vince.info",locale_CN);// ResourceBundle r = ResourceBundle.getBundle("com.vince.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"));String welcome = r.getString("welcome");//动态文本格式化welcome = MessageFormat.format(welcome, username);System.out.println(welcome);}else {System.out.println(r.getString("login.error"));}}}/*员工管理系统输入用户名:admin输入密码:123登录成功欢迎你,adminEMP Manager SystemInput UserName:adminInput Password:123Login Success!welcome,admin*/
info_zh_CN.properties
system.name=\u5458\u5DE5\u7BA1\u7406\u7CFB\u7EDFinput.username=\u8F93\u5165\u7528\u6237\u540D\uFF1Ainput.password=\u8F93\u5165\u5BC6\u7801\uFF1Alogin.success=\u767B\u5F55\u6210\u529Flogin.error=\u767B\u5F55\u9519\u8BEFwelcome=\u6B22\u8FCE\u4F60\uFF0C{0}
info_en_US.properties
system.name=EMP Manager Systeminput.username=Input UserName:input.password=Input Password:login.success=Login Success!login.error=Login Errorwelcome=welcome,{0}

5、Math与Random类
(1)Math类
Math 类包含用于执行基本数学运算的方法, 如初等指数、 对数、 平方根和三角函数。
使用Math类可以有两种方式:
- 直接使用(Math所在的包java.lang为默认引入的包)
- 使用 import static java.lang.Math.abs; 静态导入

(2)Random类
Random: 此类的实例用于生成伪随机数流

import static java.lang.Math.floor; //静态导入import java.util.Random;public class MathRandomDemo {public static void main(String[] args) {System.out.println(Math.PI);System.out.println(Math.abs(-10));System.out.println(Math.round(Math.random()*1000)/1000.0); //应用random以及round取三位小数System.out.println(Math.sqrt(2));System.out.println(floor(1.234564));Random r = new Random();System.out.println(r.nextLong());System.out.println(r.nextInt(10));}}/*3.141592653589793100.4611.41421356237309511.033521286503736445617*/
6、日期操作类
(1)Date类
类 Date 表示特定的瞬间, 精确到毫秒, 也就是程序运行时的当前时间。
Date date = new Date(); // 实例化Date对象, 表示当前时间
(2)Calendar类
Calendar, 日历类, 使用此类可以将时间精确到毫秒显示。
//两种实例化方式
Calendar c = Calendar.getInstance();Calendar c = new GregorianCalendar();
(3)DateFormat类及子类SimpleDateFormat
package com.vince;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.GregorianCalendar;public class DateDemo {public static void main(String[] args) {Date date = new Date();// java.sql.Date sqlDate = new java.sql.Date();System.out.println(date);// 使用两个构造方法// Date(long date) 参数是毫秒// Date()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());DateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS");String nowDate = df.format(new Date());System.out.println(nowDate);}}/*Sat Oct 16 23:29:20 CST 20212021年9月16日23:29:20 1472021年10月16日 23:29:20 179*/
7、对象比较器Arrays.sort()
对两个或多个数据项进行比较, 以确定它们是否相等, 或确定它们之间的大小关系及排列顺序称为比较。
前面我学习过Arrays.sort方法可实现对象的排序操作:
public static void sort(Object[] a)
(1) Comparable接口:
此接口强行对实现它的每个类的对象进行整体排序。 这种排序被称为类的自然排序, 类的compareTo 方法被称为它的自然比较方法。
(2) Comparator接口:
Comparable接口是要求自定义类去实现, 按照OO原则: 对修改关闭, 对扩展开放。那么如果这个类已经定义好了, 不想再去修改它, 那如何实现比较呢?
Comparator接口: 强行对某个对象collection进行整体排序的比较
Test
import java.util.Arrays;public class Test {public static void main(String[] args) {int[] nums = {34,54,22,3,5,6,7,87,9};Arrays.sort(nums);System.out.println(Arrays.toString(nums)); //[3, 5, 6, 7, 9, 22, 34, 54, 87]String[] names = {"jack","tom","菲菲","你好"};Arrays.sort(names);System.out.println(Arrays.toString(names)); //[jack, tom, 你好, 菲菲]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]]Dog[] dogs = {new Dog("愤愤",1),new Dog("菲菲",4),new Dog("Tom",2)};Arrays.sort(dogs,new DogComparator());System.out.println(Arrays.toString(dogs));//[Dog [name=愤愤, age=1], Dog [name=Tom, age=2], Dog [name=菲菲, age=4]]}}
Cat
/*** 自定义对象,要实现比较排序* 1、可以实现Comparable的comparaTo方法* @author vince* @description*/public class Cat implements Comparable<Cat>{private String name;private int age;public Cat() {super();}public Cat(String name, int age) {super();this.name = name;this.age = age;}@Overridepublic String toString() {return "Cat [name=" + name + ", age=" + age + "]";}@Overridepublic 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;}}
Dog
public class Dog {private String name;private int age;@Overridepublic String toString() {return "Dog [name=" + name + ", age=" + age + "]";}public Dog(String name, int age) {super();this.name = name;this.age = age;}public Dog() {super();}}
DogComparator
import java.util.Comparator;public class DogComparator implements Comparator<Dog>{@Overridepublic int compare(Dog o1, Dog o2) {return o1.getAge()-o2.getAge();}}
8、对象的克隆
将一个对象复制一份, 称为对象的克隆技术。
在Object类中存在一个clone()方法:
protected Object clone() throws CloneNotSupportedException
如果某个类的对象要想被克隆, 则对象所在的类必须实现Cloneable接口。 此接口没有定义任何方法, 是一个标记接口
Cat
/*** 对象需要具备克隆功能:* 1、实现Cloneable接口,(标记接口)* 2、重写Object类中的clone方法* @author vince* @description*/public class Cat implements Cloneable{private String name;private int 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;}public Cat(String name, int age) {super();this.name = name;this.age = age;}public Cat() {super();}//重写Object中的clone方法@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}@Overridepublic String toString() {return "Cat [name=" + name + ", age=" + age + "]";}}
Test
package com.vince;import java.io.IOException;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();}}}
9、System与 Runtime类
System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。 该类位于java.lang包。
(1)成员变量
System类内部包含in、out和err三个成员变量, 分别代表标准输入流(键盘输入), 标准输出流(显示器)和标准错误输出流。
(2)成员方法
System类中提供了一些系统级的操作方法
- public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
该方法的作用是数组拷贝, 也就是将一个数组中的内容复制到另外一个数组中的指定位置, 由于该方法是native方法, 所以性能上比使用循环高效。 - public static long currentTimeMillis()
该方法的作用是返回当前的计算机时间, 时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数 - public static void exit(int status)
该方法的作用是退出程序。 其中status的值为0代表正常退出, 非零代表异常退出。 使用该方法可以在图形界面编程中实现程序的退出功能等。 - public static void gc()
该方法的作用是请求系统进行垃圾回收。 至于系统是否立刻回收, 则取决于系统中垃圾回收算法的实现以及系统执行时的情况。 - public static String getProperty(String key)
该方法的作用是获得系统中属性名为key的属性对应的值。
java.version Java 运行时环境版本
java.home Java 安装目录
os.name 操作系统的名称
os.version 操作系统的版本
user.name 用户的账户名称
user.home 用户的主目录
user.dir 用户的当前工作目录
Runtime类: 每个 Java 应用程序都有一个 Runtime 类实例, 使应用程序能够与其运行的环境相连接。
//获取Java运行时相关的运行时对象Runtime rt = Runtime.getRuntime();System.out.println("处理器数量: " + rt.availableProcessors()+" 个");System.out.println("Jvm总内存数 : "+ rt.totalMemory()+" byte");System.out.println("Jvm空闲内存数: "+ rt.freeMemory()+" byte");System.out.println("Jvm可用最大内存数: "+ rt.maxMemory()+" byte");//在单独的进程中执行指定的字符串命令。rt.exec("notepad");
package com.vince;import java.io.IOException;import java.math.BigDecimal;import java.math.BigInteger;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.Date;public class SystemRuntimeDemo {public static void main(String[] args) {System.out.println("向控制台输出");System.err.println("出错啦");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));System.out.println(System.currentTimeMillis());Date nowDate = new Date(System.currentTimeMillis());DateFormat df = new SimpleDateFormat("HH:mm:ss");String now = df.format(nowDate);System.out.println(now);//退出JVM//System.exit(0);System.out.println(System.getProperty("java.version"));System.out.println(System.getProperty("java.home"));System.out.println(System.getProperty("os.name"));Runtime rt = Runtime.getRuntime();System.out.println("处理器数量:" + rt.availableProcessors()+" 个");System.out.println("Jvm总内存数 :"+ rt.totalMemory()+" byte");System.out.println("Jvm空闲内存数: "+ rt.freeMemory()+" byte");System.out.println("Jvm可用最大内存数: "+ rt.maxMemory()+" byte");//在单独的进程中执行指定的字符串命令。try {rt.exec("notepad"); //打开记笔本} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//加载C、C++编写的类库//System.loadLibrary(libname)}}
10、 数字处理工具类
(1)BigInteger
可以让超过Integer范围内的数据进行运算。
构造方法: public BigInteger(String val)
常用方法:
public BigInteger add(BigInteger val)public BigInteger subtract(BigInteger val)public BigInteger multiply(BigInteger val)public BigInteger divide(BigInteger val)public BigInteger[] divideAndRemainder(BigInteger val)
(2)BigDecimal
由于在运算的时候, float类型和double很容易丢失精度, 为了能精确的表示、 计算浮点数, Java提供了BigDecimal,不可变的、 任意精度的有符号十进制数。
构造方法: public BigDecimal(String val)
常用方法:
public BigDecimal add(BigDecimal augend)public BigDecimal subtract(BigDecimal subtrahend)public BigDecimal multiply(BigDecimal multiplicand)public BigDecimal divide(BigDecimal divisor)
(3)DecimalFormat:
Java 提供 DecimalFormat类, 帮你用最快的速度将数字格式化为你需要的样子。
例如, 取2位小数。
示例:
double pi=3.1415927; //圆周率//取一位整数, 结果: 3System.out.println(new DecimalFormat("0").format(pi));//取一位整数和两位小数, 结果3.14System.out.println(new DecimalFormat("0.00").format(pi));//取两位整数和三位小数, 整数不足部分以0填补, 结果: 03.142System.out.println(new DecimalFormat("00.000").format(pi));//取所有整数部分, 结果: 3System.out.println(new DecimalFormat("#").format(pi));//以百分比方式计数, 并取两位小数, 结果: 314.16%System.out.println(new DecimalFormat("#.##%").format(pi));
import java.math.BigDecimal;import java.math.BigInteger;import java.text.DecimalFormat;import java.util.Arrays;public class Test {public static void main(String[] args) {//大整数运算String val1 = "84567890986544567";String val2 = "45097659985495567";BigInteger b1 = new BigInteger(val1);BigInteger b2 = new BigInteger(val2);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))); // / and %String val3 = "5696.698494847898754789";String val4 = "6";BigDecimal b3 = new BigDecimal(val3);BigDecimal b4 = new BigDecimal(val4);System.out.println(b3.add(b4));System.out.println(b3.subtract(b4));System.out.println(b3.multiply(b4));System.out.println(b3.divide(b4));//System.out.println(b3.scale()-b4.scale());double pi=3.1415927;//圆周率//取一位整数,结果:3System.out.println(new DecimalFormat("0").format(pi));//取一位整数和两位小数,结果3.14System.out.println(new DecimalFormat("0.00").format(pi));//取两位整数和三位小数,整数不足部分以0填补,结果:03.142System.out.println(new DecimalFormat("00.000").format(pi));//取所有整数部分,结果:3System.out.println(new DecimalFormat("#").format(pi));//以百分比方式计数,并取两位小数,结果:314.16%System.out.println(new DecimalFormat("#.##%").format(pi));long num = 635463773;System.out.println(new DecimalFormat("###,###").format(num));}}/*129665550972040134394702310010490003813813993401642148647580426434489139470231001049000[1, 39470231001049000]5702.6984948478987547895690.69849484789875478934180.190969087392528734949.449749141316459131533.1403.1423314.16%635,463,773*/
11、 MD5工具类
MD5的全称是Message-Digest Algorithm 5(信息-摘要算法)
//确定计算方法MessageDigest md5=MessageDigest.getInstance("MD5");//JDK1.8新增Base64String newstr = Base64.getEncoder().encodeToString(md5.digest(str.getBytes("utf-8")));//1.8之前使用sun.misc.BASE64Encoder(此类没有访问权限, 在rt.jar中添加访问权限: sun/misc/*)BASE64Encoder base64 = new BASE64Encoder();base64.encode(md5.digest(str.getBytes("utf-8")));
package com.vince;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Arrays;import java.util.Base64;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public class MD5Demo {private static String savePassword = "pmq7VoTEWWLYh1ZPCDRujQ==";//存储的密文public static void main(String[] args) {test();System.out.println(login("admin123456"));}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");//通过MD5计算摘要byte[] bytes = md.digest(password.getBytes("UTF-8"));String str = Base64.getEncoder().encodeToString(bytes);return str;} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return null;}private static void test() {String password = "admin123456"; //dsfkjdskfj76776f98732 明文(原文)String savePassword = "pmq7VoTEWWLYh1ZPCDRujQ==";//存储的密文try {MessageDigest md = MessageDigest.getInstance("md5");//通过MD5计算摘要byte[] bytes = md.digest(password.getBytes("UTF-8"));System.out.println(Arrays.toString(bytes));String mdStr = new String(bytes);//System.out.println(mdStr);//a-z A-Z 0-9 / * BASE64编码算法// 1.8版本String str = Base64.getEncoder().encodeToString(bytes);System.out.println(str);//JDK1.8之前使用// BASE64Encoder base64 = new BASE64Encoder();// String str = base64.encode(bytes);//base64解码BASE64Decoder decoder = new BASE64Decoder();byte[] bs = decoder.decodeBuffer(str);System.out.println(Arrays.toString(bs));} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}/*[-90, 106, -69, 86, -124, -60, 89, 98, -40, -121, 86, 79, 8, 52, 110, -115]pmq7VoTEWWLYh1ZPCDRujQ==[-90, 106, -69, 86, -124, -60, 89, 98, -40, -121, 86, 79, 8, 52, 110, -115]true*/
12、Lambda表达式
(1)Lambda表达式
Lambda表达式(也称为闭包) 是整个Java 8发行版中最受期待的在Java语言层面上的改变, Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据。
Lambda表达式用于简化JAVA中接口式的匿名内部类。 被称为函数式接口的概念。 函数式接口就是一个具有一个方法的普通接口。 像这样的接口, 可以被隐式转换为lambda表达式。
语法:
(参数1,参数2…) -> { … }
- 没有参数时使用Lambda表达式
- 带参数时使用Lambda表达式
- 代码块中只一句代码时使用Lambda表达式
- 代码块中有多句代码时使用Lambda表达式
- 有返回值的代码块
- 参数中使用final关键字
(2)接口中的默认方法和静态方法
interface A{public default void print(){}public static void method(){}}
默认方法与静态方法并不影响函数式接口的契约, 可以任意使用
package com.vince;import java.util.Arrays;import java.util.Comparator;public class LambdaDemo {public static void main(String[] args) {// IEat ieat = new IEatImpl();// ieat.eat();// IEat ieat2 = new IEat(){// public void eat(){// System.out.println("eat banana");// }// };// ieat2.eat();//lambda表达式://好处:1代码更简洁,2,不会单独生成class文件// IEat ieat3 = ()->{System.out.println("eat apple banana");};//没有参数时使用// IEat ieat3 = ()-> System.out.println("eat apple banana");// ieat3.eat();//带参数时使用,参数的类型可以省略// IEat ieat3 = (thing,name) -> System.out.println("eat..."+thing+"..."+name);// ieat3.eat("apple","大冰");//带参数时使用,参数的类型可以省略,代码块中有多行代码// IEat ieat3 = (thing,name) -> {// System.out.println("eat..."+thing);// System.out.println(name);// };// ieat3.eat("apple","大冰");//带返回值的方法// IEat ieat3 = (thing,name)->{// System.out.println(name+ " eat "+thing);// return 10;// };//带返回值 的方法中只有一句实现代码IEat ieat3 = (final String thing,final String name)-> thing==null?1:0;ieat3.eat("apple", "大冰");Student[] students = {new Student("张三",18),new Student("张四",28),new Student("张一",15)};// Arrays.sort(students,new Comparator<Student>() {// public int compare(Student o1, Student o2) {// return o1.getAge()-o2.getAge();// };// });// Comparator<Student> c = (o1,o2)->o1.getAge()-o2.getAge();Arrays.sort(students,(o1,o2)-> o1.getAge()-o2.getAge());System.out.println(Arrays.toString(students));IEat.method();}}//只有一个抽象方法的接口interface IEat{public int eat(final String thing,final String name);public default void print(){System.out.println("print test");}public static void method(){System.out.println("static method..");}}//class IEatImpl implements IEat{// public void eat(String thing){// System.out.println("eat--"+thing);// }//}
package com.vince;public class Student {private String name;private int 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;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}public Student(String name, int age) {super();this.name = name;this.age = age;}public Student() {super();// TODO Auto-generated constructor stub}}
