目录
Lambda表达式
体验Lamdba表达式
goSwimming(new Swimming() {
public void swim() {
System.out.println("帖子我们去游泳吧");
}
});
goSwimming(() -> System.out.println("帖子我们去游泳吧"));
函数式编程思想概述
在数学中,函数就是有输入量,输出量的一套计算方案,也就是"拿数据做操作" 面向对象思想强调"必须通过对象形式来做事情"
函数式思想则尽量忽略面向对象的复杂语法:"强调做什么,而不是以什么形式去做" 学习Lambda表达式就是函数式思想的体现
Lambda表达式的标准格式
匿名内部类中重写swim()方法的代码分析
方法形式参数为空,说明调用方法时不需要传递参数
方法返回值类型为void,说明方法执行没有结果返回
方法体中的内容,是我们具体要做的事情
Lambda表达式的代码分析
():里面没有内容,可以看成是方法形式参数为空
->:用箭头指向后面要做的时期
{}:包含一段代码,我们称之为代码块,可以看成是方法体重的内容
goSwimming(() -> {
System.out.println("帖子我们去游泳吧");
});
组成Lambda三要素:形式参数,箭头,代码块;
格式
(形式参数) -> {代码块}
形式参数:如果有多个参数,参数之间要用逗号隔开;如果没有参数,留空即可。
->:由英文中画线和大于符号组成,固定写法,代表动作指向。
使用前提
有一个接口
有且只有一个抽象方法
public class Test {
public static void main(String[] args) {
/* useShowHandler(new ShowHandler() {
@Override
public void show() {
System.out.println("啊哈哈");
}
});*/
useShowHandler(() -> {
System.out.println("hahah");
});
}
public static void useShowHandler(ShowHandler ha) {
ha.show();
}
}
interface ShowHandler {
void show();
}
例子:带参数有返回值
public class Test6 {
public static void main(String[] args) {
useInter((double a,double b) ->{
return a+b;
});
}
public static void useInter(Inter i){
double result = i.method(12.3,22.3);
System.out.println(result);
}
}
interface Inter{
double method(double a,double b);
}
表达式省略模式
规则:
参数类型可以省略,但是有多个参数的情况下,不能只省略一个。
如果参数有且仅有一个,那么小括号可以省略。
如果代码快的语句只有一条,可以省略大括号和分号,甚至是return。
public static void main(String[] args) {
/* useInter((double a,double b) ->{
return a+b;
});*/
useInter((a,b) ->
a+b
);
}
Lambda表达式与匿名表达式的区别
所需类型不同
匿名内部类:可以是接口,也可以是抽象类,还可以是具体类。
Lambda表达式:只能是接口。
使用限制不同
如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类。
如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式。
实现原理不同
匿名内部类:编译之后,产生一个单独的.class字节码文件。
Lambda表达式:编译之后,没有一个单独.class字节码文件。对应的字节码会在运行时候动态生成。
API
什么是API?
应用程序接口
简单来说:就是Java帮我们已经写好的一些方法,我们直接拿过来用就可以了。
Math
Math概述
包含执行基本数字运算的方法
没有构造方法,如何使用类中的成员呢?
看类的成员是否都是静态的,如果是,通过类名就可以直接调用。
public static void main(String[] args) {
//public static int abs(int a) 返回参数的绝对值
int a =Math.abs(5);
System.out.println(a);
//public static double ceil(double a) 向上取整
double b = Math.ceil(10.1);
System.out.println(b);
//public static double floor(double a) 向下取整
double c = Math.floor(10.1);
System.out.println(c);
//public static int round(float a) 四舍五入
double d = Math.round(5.3);
System.out.println(d);
///public static int max(int a,int b) 返回两个int值中的较大值
int e = Math.max(4,6);
System.out.println(e);
//public static int min(int a, int b) 返回两个int值中的较小值
int f = Math.min(6,5);
System.out.println(f);
//public static double pow(double a,double b) 返回a的b次幂的值
double j = Math.pow(2,3);
System.out.println(j);
//public static double random() 返回值为double的正值,范围[0.0,1.0) 返回随机数
double h = Math.random();
System.out.println(h);
}
System类常用方法
System.exit(0); //当代码执行到这个方法的时候,就表示虚拟机已经停止了
int [] arr1 = {1,2,3,4,5};
int [] arr2 = new int[10];
System.arraycopy(arr1,0,arr2,0,arr1.length)//把arr1拷贝到arr2中
Object
概述:每个类都有可以将Object作为父类。所有类都直接或者间接的继承自该类。
构造方法:public Object()
结论
Object类是所有类的直接或者间接父类。
直接打印一个对象就是打印这个对象的toString方法的返回值。
Object类的toString方法得到的是对象的地址值。
我们一般会对toString方法进行重写。
Object类的常用方法
Objects
第一个方法返回对象字符串的表现形式
第二个方法,判断对象是否为空,如果为空,返回默认字符串(自己随便写),如果对象不为空,调用toString方法。
第三个,如果对象为空,返回true,不为空返回false。
第四个方法与第三个相反。
BigDecimal类
BigDecimal类的构造方法
计算机在计算过程,把数从十进制转换为二进制进行计算,在转换为十进制进行输出,因为计算机机制问题,小数从十进制转换为二进制丢失数据,输出无限接近的的小数。
public static void main(String[] args) {
BigDecimal b1 = new BigDecimal(10.0);
BigDecimal b2 = new BigDecimal("0.3");
System.out.println(b1);//10
System.out.println(b2);//0.3
}
BigDecimal类的常用方法
作用:可以用来精确计算
public static void main(String[] args) {
// public BigDecimal add(另一个BigDecimal对象) 加法
//想要精确运算,要用字符串构造
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.2");
BigDecimal add = b1.add(b2);
System.out.println(add);
// public BigDecimal subtract(另一个BigDecimal对象) 减法
BigDecimal subtract = b2.subtract(b1);
System.out.println(subtract);
// public BigDecimal multipy(另一个BigDecimal对象) 乘法
BigDecimal multipy = b2.multiply(b1);
System.out.println(multipy);
// public BigDecimal divide (另一个BigDecimal对象) 除法
BigDecimal divide = b2.divide(b1);
System.out.println(divide);
}
特殊方法
基本数据类型包装类
Integer类的概述和使用
Integer:该对象中包装了一个基本数据类型int的值
//public static Integer valueOf(int i) 返回表示指定的int值的Integer实例
Integer i3 = Integer.valueOf(200);
System.out.println(i3);
//public static Integer valueOf(String s) 返回一个保存指定值的Integer对象String
Integer i4 = Integer.valueOf("200");
System.out.println(i4);
自动装箱和自动拆箱
装箱:把基本数据类型转换为对应的包装类类型
拆箱:把包装类类型转换为对应的基本数据类型
Integer i =100; //自动装箱
i +=200; //i = i+200; i+200是自动拆箱;i=i+200;是自动装箱
注意:在使用包装类类型的时候,如果做操作,最好线判断是否为null,推荐的是,只要是对象,在使用前就必须进行不为null的判断。
Integer的成员方法
基本类型包装类的最常见操作就是:用于基本类型和字符串之间的相互转换
-
int转换为String
方式一:加双引号即可
方式二:public static String valueOf(int i):返回int参数的字符串表示形式。该方法是String类中的方法。 -
String 转换为int
public static int parselnt(String s):将字符串解析为int类型。该方法是lnteger类中的方法。
public static void main(String[] args) {
String s1 = "100";
int i1 = 200;
int i2 = Integer.parseInt(s1);//可以将字符串类型的整数变成int类型的整数
System.out.println(i2+i1);
//int ---> String
//方式一:+""
int i3=100;
String s2 =i3+"";
System.out.println(s2+100);
//方式二:可以调用String类中valueof方法
String s3 = String.valueOf(i3);
System.out.println(s3+100);
}
需求:有一个字符串:"91 27 46 38 50",把其中的每一个数存到int类型的数组中
public static void main(String[] args) {
String s ="91 27 46 38 50";
//获取字符串的每一个数字
String[] strArr = s.split(" ");
//创建一个int数组
int[] numberArr = new int[strArr.length];
//string类型转换为int类型
for (int i = 0; i < strArr.length; i++) {
int number = Integer.parseInt(strArr[i]);
numberArr[i]=number;
}
//遍历int数组
for (int i = 0; i < numberArr.length; i++) {
System.out.println(numberArr[i]);
}
}
数组的高级操作
数组的二分查找步骤
-
定义两个变量,表示要查找的范围。默认min=0,max=最大索引
-
循环查找,但是min<=max
-
计算出mid的值
-
判断mid位置的元素是否为要查找的元素,如果是直接返回对应索引
-
如果要查找的值在mid的左半边,那么min值不变,max=mid-1.继续下次循环查找。
-
如果要查找的值在mid的右半边,那么max值不变,min=mid+1.继续下次循环查找
-
当min>max时,表示要查找的元素在数组中不存在,返回-1.
//1 我现在要干什么? 二分查找
//2 我干这件事需要什么? 数组 元素
//3 我干完了,要不要把结果返回调用者 把索引返回给调用者
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9};
int number = 3;
int index = binarySearchForIndex(arr, number);
System.out.println(index);
}
private static int binarySearchForIndex(int[] arr,int number){
//1.定义查找范围
int min = 0;
int max=arr.length-1;
//2循环查找
while (min <=max){
//3.计算出中间位置mid
int mid = min+max>>1;//(min+max)/2
if (arr[mid]>number){
//在左边
max=mid-1;
}else if (arr[mid]<number){
//在右边
min=mid+1;
}else{
return mid;
}
}
//如果min大于了max就表示元素不存在返回-1;
return -1;
}
递归
递归概述:以变成的角度来看,递归指的是方法定义中调用方法本身的现象
递归解决问题的思路:
把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
递归册罗只需要少量的程序就可以描述出解题过程所需要的多次重复计算
递归解决问题要找到两个内容:
-
递归出口:否则会出现内存溢出
-
递归规则:与原问题相似的规模较小的问题
需求:输入一个数n,用递归求n的阶乘,并把结果在控制台输出
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字:");
int i = sc.nextInt();
int index = gitcheng(i);
System.out.println(index);
}
private static int gitcheng(int i) {
//出口
if (i==1){
return 1;
}else{
//递归规则
return i*gitcheng(i-1);
}
}
快速排序
冒泡排序算法中,一次循环结束,就相当于确定了当前的最大值,也能确定最大值在数组中应存入的位置。
快速排序算法中,每一次递归时以第一个数为基准数,找到数组中所有比基准数小的。再找到所有比基准数大的。小的全部放在左边,大的全部放在右边,确定基准数的正确位置。
public static void main(String[] args) {
int[] arr={6,1,2,7,9,3,4,5,10,8};
getKP(arr,0,arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
private static void getKP(int[] arr,int L,int R){
if (L>R){
return;
}
int L0=L;
int R0=R;
int number = arr[L0];
while (L!=R){
while (arr[R]>=number&&R>L){
R--;
}
while (arr[L]<=number&&L<R){
L++;
}
int tmp = arr[L];
arr[L]= arr[R];
arr[R]= tmp;
}
int tmp = arr[L];
arr[L]=arr[L0];
arr[L0]=tmp;
getKP(arr,L0,L-1);
getKP(arr,L+1,R0);
}
Arrays
public static void main(String[] args) {
int[] arr = {3,2,4,6,7};
// public static String toString(int[] a) 返回指定数组的内容的字符串表示形式
System.out.println(Arrays.toString(arr));
// public static void sort(int[] a) 按照数字顺序排列指定的数组
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));//[2, 3, 4, 6, 7]
// public static int binarySearch (int[] a,int key) 利用二分查找返回指定元素的索引
int index = Arrays.binarySearch(arr,7);
System.out.println(index);//4
//1.数组必须有序
//2.如果要查找的元素存在,那么返回的时这个元素实际的索引
//3.如果要查找的元素存在,那么返回的时(-插入点-1)
//插入点:如果这个元素在数组中,他应该再哪个索引上。
}