一、Math类
Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数
我们查看math类的常用方法:
我们查看他的源码如下所示:
我们查看他的类图:
他的这些方法基本都是静态的:
我们的代码设置如下所示:
package com.ypl.Math_; public class MathMethod_ { public static void main(String[] args) { //Math常用的方法(静态方法) //1.abs 绝对值 int abs = Math.abs(-9); System.out.println(abs);//9 //2.pow 求幂 double pow = Math.pow(2, 4); //2的4次方 System.out.println(pow); //16 //3.ceil 向上取整,返回>=该参数的最小整数(转成double) double ceil = Math.ceil(-3.0001); System.out.println(ceil);//-3 //4.floor 向下取整,返回<=该参数的最大整数(转成double) double floor = Math.floor(-4.999); System.out.println(floor);//-5.0 //5.round 四舍五入 Math.floor(该参数+0.5) long round = Math.round(-5.001); System.out.println(round); //6.sqrt 求开方 double sqrt = Math.sqrt(9.0); System.out.println(sqrt); //3.0 //7.random 求随机数 //random 返回的是0<=x<1之间的一个随机小数。 //思考:请写出获取a-b之间的一个随机整数,a,b均为整数,比如a=2,b=7. // 即返回一个数 x , 2<=x<=7 . //Math.random()*(b-a)返回的就是0<= X <= b-a //(1)(int)(a)<=x<=(int)(a+ Math.random()*(b-a+1)) //(2)使用具体的数进行解释如下: //a= 2 b=7 //(int)(a+Math.random( )*(b-a +1))=(int)(2+Math.random( )*(6) //Math.random( )*6 返回的是 0<=x<6 小数 //2+Math.random( )*6 返回的就是 2<=x<8 //(int)2+Math.random( )*6 = 2<=x<=7 //(3)公式就是 (int)(a+ Math.random()*(b-a+1)) //如果写成(int)(b)即为一个固定的值,而(int)(a + b-a)可以进行如上操作 for (int i = 0; i< 3; i++) { System.out.println((int)(2+Math.random()*(7-2+1 ))); } //获取一个a-b之间的一个随机整数 //int num=(int)(Math.random()*(b-a +1)+a); //max,min返回最大值和最小值 System.out.println("max="+Math.max(55,99));//99 System.out.println("min="+Math.min(66,88));//66 } }
我们运行之后如下所示:
我们了解到规律如下所示:
获取一个a-b之间的一个随机整数
int num=(int)(Math.random()*(b-a +1)+a);
二、Arrays类
Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索)
(1)toString 返回数组的字符串形式
我们按以前的方式如下所示:
package com.ypl.Arrays_; public class ArrayMethod01 { public static void main(String[] args) { Integer[] integers={1,20,90}; //遍历数组 for (int i=0;i<integers.length;i++){ System.out.println(integers); } } }
我们运行之后如下所示:
我们 采用toString方法如下所示:
package com.ypl.Arrays_; import java.util.Arrays; public class ArrayMethod01 { public static void main(String[] args) { Integer[] integers={1,20,90}; //遍历数组 //直接使用Arrays.toString方法,显示数组。 System.out.println(Arrays.toString(integers)); } }
我们运行之后如下所示:
我们查看toString的源码如下所示:
public static String toString(Object[] a) { if (a == null) return "null"; int iMax = a.length - 1; if (iMax == -1) return "[]"; StringBuilder b = new StringBuilder(); b.append('['); for (int i = 0; ; i++) { b.append(String.valueOf(a[i])); if (i == iMax) return b.append(']').toString(); b.append(", "); } }
(2)sort 排序(自然排序和定制排序) Integer arr[ ] ={1,-1,7,0,89};
我们可以通过这个方法Comparator这个比较器,可以指定排序的规则是什么,可以选择从大到小,也可以选择从小到大。可以根据自己的想法去设计。
我们设计的代码如下所示:
package com.ypl.Arrays_; import java.util.Arrays; import java.util.Comparator; public class ArrayMethod01 { public static void main(String[] args) { //演示sort方法的使用 Integer arr[]={1,-1,7,0,89}; //进行排序 //1.可以直接使用冒泡排序,也可以直接使用Arrays提供的sort方法排序 //2.因为数组是引用类型,所以通过sort排序后,会直接影响到实参 arr. //3.sort重载的,也可以通过传入一个接口 Comparator 实现定制排序 //4.Arrays.sort(arr) 默认排序方法。 //默认排序 Arrays.sort(arr); System.out.println("=====排序后====="); System.out.println(Arrays.toString(arr)); //5.调用定制排序时,传入两个参数(1)排序的数组 arr //(2)实现了Comparator接口的匿名内部类,要求实现 compare方法 //6.这里体现了接口编程的方式 //源码分析: //(1) Arrays.sort(arr, new Comparator() //(2)最终到TimeSort的 // private static <T> void binarySort(T[] a, int lo, int hi, int start, //Comparator<? super T> c) //(3)执行到binarySort方法的代码,会根据动态绑定机制c.compare( )执行我们传入的匿名内部类compare( )方法. //while (left < right) { // int mid = (left + right) >>> 1; // if (c.compare(pivot, a[mid]) < 0) // right = mid; // else // left = mid + 1; // } //(4) new Comparator() { // @Override // public int compare(Object o1, Object o2) { // Integer i1 = (Integer) o1; // Integer i2 = (Integer) o2; // // return i2-i1; // } // }); //(5) public int compare(Object o1, Object o2)方法返回的值>0的还是<0的会影响整个排序的结果 //这就充分体现了接口编程+动态绑定+匿名内部类的综合使用 //将来的底层框架和源码的使用方式,会非常常见。 //定制排序 Arrays.sort(arr, new Comparator() { @Override public int compare(Object o1, Object o2) { Integer i1 = (Integer) o1; Integer i2 = (Integer) o2; return i2-i1; } }); System.out.println("=====排序后====="); System.out.println(Arrays.toString(arr)); } }
我们在运行的时候,我们会先调用sort方法,这个sort方法底层会调用Comparator接口。
我们运行之后如下所示:
我们通过debug来看待如何进行的自己定义的排序:
我们在如下地方打断点:
我们追进去如下所示:
我们传进去一个匿名类,所以不为null。
我们发现底层其实是二叉树排序:
我们继续进去如下所示:
在binarySort方法底层,会通过实现的匿名内部类的compare方法来决定排序的顺序
在排序的底层,它调用了传入的接口实现的compare方法。
我们通过模拟排序来加深对排序的认识:
我们设计的代码如下所示:
package com.ypl.Arrays_; import java.util.Arrays; import java.util.Comparator; public class ArraysSourtCustom { public static void main(String[] args) { int [] arr={1,-1,8,0,20}; bubble01(arr); System.out.println("默认排序为:"+Arrays.toString(arr)); bubble02(arr, new Comparator() { @Override public int compare(Object o1, Object o2) { int i1=(Integer) o1; int i2=(Integer)o2; return i2-i1; //return i2-i1; } }); System.out.println("===定制排序后的情况==="); System.out.println(Arrays.toString(arr)); } //使用冒泡完成排序 public static void bubble01(int [] arr){ int temp=0; for (int i=0;i<arr.length-1;i++){ for (int j=0;j< arr.length-1-i;j++){ //从小到大 if(arr[j]>arr[j+1]){ temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } } //结合冒泡+定制 public static void bubble02(int [] arr, Comparator c){ int temp=0; for (int i=0;i<arr.length-1;i++){ for (int j=0;j< arr.length-1-i;j++){ //数组排序由c.compare(arr[j],arr[j+1])返回的值决定 if(c.compare(arr[j],arr[j+1])>0) { temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } } }
我们运行之后如下所示:
我们通过debug来进行更加清晰的认识:
我们继续进行追加进去如下所示:
我们继续进行下一步,如下所示:其中c.compare就是我们传进去的匿名对象的Comparator,里面有动态绑定,我们进去step into,如下所示:会将arr[j]和arr[j+1]这两个元素传递给我们传入的匿名的类。
(3) binarySearch 通过二分搜索法进行查找,要求必须排好序
int index =Arrays.binarySearch(arr,3);
我们设计代码如下所示:
package com.ypl.Arrays_; import java.util.Arrays; public class ArrayMethod02 { public static void main(String[] args) { // binarySearch 通过二分搜索法进行查找,要求必须排好序 Integer[] arr={1,2,90,123,567}; //1.使用binarySearch 二叉查找 //2.要求该数组是有序的,如果该数组是无序的,不能使用 binarySearch。 int index = Arrays.binarySearch(arr, 1); System.out.println("index="+index); int i = Arrays.binarySearch(arr, 123); System.out.println("i="+i); //3.如果数组中不存在该元素,就返回-1. int i3 = Arrays.binarySearch(arr, -127); System.out.println("i3="+i3); int i1 = Arrays.binarySearch(arr, 556); System.out.println("i1="+i1); int i2 = Arrays.binarySearch(arr, 92); System.out.println("i2="+i2); } }
我们运行之后如下所示:
我们发现我们搜索不存在的数组的时候,我们返回的是-5,不是-1.我们来查看源码:
我们根据源码我们了解到,low为值应该存放的地址,我们所求的556,如果存在的话应该位于第4个,即4为源码的low值,---(4+1),为-5.
我们设计的代码如下所示:
(4)copyOf 数组元素的复制:
package com.ypl.Arrays_; import java.util.Arrays; public class ArrayMethod03 { public static void main(String[] args) { //copyOf 数组元素的复制 //1.从arr数组中,拷贝arr.length个元素到 newArr数组中 Integer [] arr={1,2,90,123,567}; Integer[] newArr = Arrays.copyOf(arr, arr.length); System.out.println("==拷贝执行哦完毕后==="); System.out.println(Arrays.toString(newArr)); //2.如果拷贝的长度>arr.length就在新数组的后面增加null。 //3.如果拷贝的长度<0就抛出异常NegativeArraySizeException //4.该方法的底层使用的是System.arraycopy( ) Integer[] integers1 = Arrays.copyOf(arr, arr.length + 1); System.out.println(Arrays.toString(integers1)); Integer[] integers = Arrays.copyOf(arr, 3); System.out.println(Arrays.toString(integers)); } }
运行之后如下所示:
我们查看copy的底层源码:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
(5) fill数组元素的填充
Integer [] num=new Integer [ ]{9,3,2};
Arrays.fill(num,99)
我们设计的代码如下所示:
package com.ypl.Arrays_; import java.sql.Array; import java.util.Arrays; public class ArrayMethod04 { public static void main(String[] args) { //fill 数组元素的填充 Integer[] num= new Integer[]{9,3,2}; //1.使用99去填充num数组,可以理解成是替换原来的元素 Arrays.fill(num,99); System.out.println("==num数组填充后=="); System.out.println(Arrays.toString(num)); } }
我们运行之后如下所示:
(6)equals 比较两个数组元素内容是否完全一致
boolean equals=Arrays.equals(arr,arr2);
我们设计的代码如下所示:
package com.ypl.Arrays_; import java.util.Arrays; public class ArrayMethod05 { public static void main(String[] args) { //equals 比较两个数组元素内容是否完全一致 Integer [] arr ={1,2,90,123,567}; Integer [] arr2={1,2,90,123,567}; Integer[] num= new Integer[]{9,3,2}; //1.如果arr 和 arr2 数组的元素一样,则返回true boolean equals = Arrays.equals(arr, arr2); //2.如果不是完全一样,就返回false. boolean equals1 = Arrays.equals(arr, num); System.out.println("equals="+equals); System.out.println("equals1="+equals1); } }
我们运行之后如下所示:
(7)aList将一组值,转换成list
Liist<Integer> aList =Arrays.aList(2,3,4,5,6,1);
System.out.println("asList="+aList);
我们设计的代码如下所示:
package com.ypl.Arrays_; import java.util.Arrays; import java.util.List; public class ArrayMethod06 { public static void main(String[] args) { //1.asList方法,会将(2,3,4,5,6,1)数据转成一个List集合 //2.返回的asList编译类型 List(接口) //3.asList 运行类型 java.util.Arrays$ArrayList,是Arrays类的静态内部类 List<Integer> asList = Arrays.asList(2, 3, 4, 5, 6, 1); System.out.println("asList="+asList); System.out.println("asList的运行类型"+asList.getClass()); } }
我们运行之后如下所示:
我们查看Arrays的类图如下所示:Arrays的内部类如下:
我们查看他的源码如下所示:
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable {
(八)课堂练习:
案例:自定义Book类,里面包含name和price,按price排序(从大到小)。要求使用两种方式排序,对对象的某个属性排序,有一个Book[ ] books=5本书对象。
使用前面学习过的传递实现Comparator接口匿名内部类,也称为定制排序。
可以按照价格price(1)从大到小 (2)从小到大 (3)按照书名长度从大到小
我们设计的代码如下:
package com.ypl.Arrays_;
import java.util.Arrays;
import java.util.Comparator;
public class ArrayExercise {
public static void main(String[] args) {
Book [] books=new Book[4];
books[0]=new Book("红楼梦~",100);
books[1]=new Book("金瓶梅新版",90);
books[2]=new Book("青年文摘20年",5);
books[3]=new Book("java从入门到放弃~",300);
//(1)price从大到小
Arrays.sort(books, new Comparator() {
//这里是对Book数组排序,因此,o1和o2就是Book对象
@Override
public int compare(Object o1, Object o2) {
Book book1 = (Book) o1;
Book book2 = (Book) o1;
return book2.getName().length() - book1.getName().length();
}
});
System.out.println(Arrays.toString(books));
}
}
class Book {
private String name;
private double price;
public Book(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
我们运行之后如下所示: