- System:
- Runtime:
- Random:
- Scanner:
- Arrays:
- MessageFormat:
- Math:
- 日期:
- Comparable:
- cloneable接口:
- 数字处理:
- MD5加密:
- lambda表达式:
- RandomAccessFile:
- Properties:
- StringUtils:
- BCryptPasswordEncoder:
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));
}
}
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);
}
}
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);
}
}
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)));
} }
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
}
}
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流可以十分方便的改成并行流的重要原因之一。
Stream接口 (1.8 之后的新特性)
import java.util.stream.Stream; public class Test {
public static void main(String[] args) {
Stream<String> stream = Stream.of("good","good","study","day","day","up");
//foreach
//stream.forEach((s)->System.out.println(s)); //结束操作,不返任何东西 //filter 过滤
//stream.filter(s->s.length()>3).forEach(System.out::println);//中间操作;filter返回一个stream; //distinct
//stream.distinct().forEach(System.out::println); //去重,中间操作 //map,实现了Function接口,Function接口是需要传递一个函数;每一个元素都需要执行这个函数;然后生成一个新的集合
//stream.map((s)->s.toUpperCase()).forEach(System.out::println); //reduce,steam中的两个元素进行操作
//Optional<String> op = stream.reduce((s1,s2)->s1.length()>s2.length()?s1:s2);
//Optional<String> op = stream.reduce((s1,s2)->s1+s2);
//System.out.println(op.get()); //collect 将stream转化成数组;
//List<String> list = stream.collect(Collectors.toList());
//list.forEach(System.out::println); //flatMap可以合并多和流;
//Stream<List<Integer>> ss = Stream.of(Arrays.asList(1,2,3),Arrays.asList(4,5));
//ss.flatMap(list->list.stream()).forEach(System.out::println);
}
}
ArrayList通过使用Stream流来处理数据
List<Integer> integers = Arrays.asList(4, 5, 6,1, 2, 3,7, 8,8,9,10);
List<Integer> evens = integers.stream().filter(i -> i % 2 == 0)
.collect(Collectors.toList()); //过滤出偶数列表 [4,6,8,8,10]<br>
List<Integer> sortIntegers = integers.stream().sorted()
.limit(5).collect(Collectors.toList());//排序并且提取出前5个元素 [1,2,3,4,5]
List<Integer> squareList = integers.stream().map(i -> i * i).collect(Collectors.toList());//转成平方列表
int sum = integers.stream().mapToInt(Integer::intValue).sum();//求和
Set<Integer> integersSet = integers.stream().collect(Collectors.toSet());//转成其它数据结构比如set
Map<Boolean, List<Integer>> listMap = integers.stream().collect(Collectors.groupingBy(i -> i % 2 == 0)); //根据奇偶性分组
List<Integer> list = integers.stream().filter(i -> i % 2 == 0).map(i -> i * i).distinct().collect(Collectors.toList());//复合操作
Stream流水中的每一个方法内部都是一个匿名内部类,我们使用Lambda表达式可以替代匿名内部类,使得代码更简单
@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);
}
}