Java小白一文简单介绍Java中的Math类、Arrays类及大数处理方案

Math类

常用方法

        //Math常用方法
        //1.abs绝对值
        int abs = Math.abs(-647);
        System.out.println(abs);//647
        //2.pow求幂
        double pow = Math.pow(2, 4);//求2的4次方
        System.out.println(pow);//16.0
        //3.ceil向上取整,返回>=该参数的最小整数
        double ceil = Math.ceil(-3.001);
        System.out.println(ceil);//-3.0
        //4.floor向下取整
        double floor = Math.floor(2.97);
        System.out.println(floor   );//2.0
        //5.round四舍五入
        long round = Math.round(99.99);
        System.out.println(round);//100
        //6.sqrt求开方
        double sqrt = Math.sqrt(9.0);
        System.out.println(sqrt);//3.0
        //7.random求随机数   random返回的是0~1之间的随机小数  [0,1)
        System.out.println(Math.random());//0.5390963838028429
        //请写出获取a~b之间的一个随机整数,a,b均为整数  2~7间
        for (int i = 0; i < 10; i++) {
            System.out.println((int)(Math.random()*6+2));
        }
        //求[a,b]间随机数的公式: (int)(a+Math.random()*(b-a+1));

        //Math.max Math.min就是返回最大值和最小值,就不演示了

Arrays类

常用方法1.0

        //1.toString返回数组的字符串形式s
        int[] arr ={6,4,7};
        String string = Arrays.toString(arr);
        System.out.println(string);//[6, 4, 7]

        //2.sort排序
        Integer arrr[] = {1,-7,6,4,7,0,99};
        //数组是引用类型,所以通过sort排序后,会直接影响到实参 arrr
        Arrays.sort(arrr);//默认的从小到大的排序
        System.out.println("排序后,可得:");
        //此时可得到从小到大的排序结果
//        System.out.println(Arrays.toString(arrr));//[-7, 0, 1, 4, 6, 7, 99]
        //那如果想实现从大到小的输出呢?
        //sort是可以重载的,也可以通过传入一个接口Comparator也就是比较器,来实现定制排序
        //调用定制排序时,传入了两个参数,1.需要排序的数组2.实现了Comparator接口的匿名内部类,要求实现了compare方法
        //定制排序
        /**
         * 剖析源码可知
         * 1.Arrays.sort(arrr, new Comparator<Integer>()
         * 2.最终到TimSort类的 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<Integer>() {
         *
         *             @Override
         *             public int compare(Integer o1, Integer o2) {
         *             //然后到这儿看你此时写的是哪个-哪个,写法会影响到回传回if的参数,最终决定走if-else中哪个逻辑
         * //                return o1-o2;
         *                 return o2-o1;
         *             }
         *         }
         * 5.public int compare(Integer o1, Integer o2) {返回的值>0 or <0
         *   会影响整个排序结果 ,这就充分体现了接口编程+动态绑定++匿名内部类的综合使用
         */
        Arrays.sort(arrr, new Comparator<Integer>() {//这里有没有想起来之前讲的匿名内部类呢hhh

            @Override
            public int compare(Integer o1, Integer o2) {
//                return o1-o2;//此时底下输出的是按照从小到大的结果[-7, 0, 1, 4, 6, 7, 99]
                return o2-o1;//[99, 7, 6, 4, 1, 0, -7]
            }
        });
        System.out.println(Arrays.toString(arrr));

定制冒泡排序接口来sort

    public static void main(String[] args) {
        int[] arr = {6, 4, 7,1,-1,0};
//        bubbleSort(arr);//正常的冒泡排序
        bubble2(arr, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //重写
                 int i1 = (Integer)o1;//拆箱
                 int i2 = (Integer)o2;
                 //此时是按照从小到大排.输出-1 0 1 4 6 7 
                 return i1-i2;//这里的谁-谁,决定c.compare(arr[j],arr[j+1])
                //返回的值的正负,进而决定是否进入内部swap,如果大于0,则swap,
                //进而决定了数组最后排序的呈现顺序是从小到大的
                //接下来是想按照从大到小排输出的写法
//                return i2-i1;//7 6 4 1 0 -1
            }
        });
        for(int i :arr){
            System.out.print(i+" ");
        }
    }

    //使用冒泡完成排序
    public static void bubbleSort(int[] arr){
        if(arr==null || arr.length<0){
            return;
        }
        for(int e = arr.length-1;e>0;e--){
            for(int j=0;j<e;j++){
                if(arr[j]>arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
    //结合冒泡+定制
    public static void bubble2(int[] arr,Comparator c){
        if(arr==null || arr.length<0){
            return;
        }
        for(int e = arr.length-1;e>0;e--){
            for(int j=0;j<e;j++){
                //数组排序由c.compare(arr[j],arr[j+1])返回的值决定
                if(c.compare(arr[j],arr[j+1])>0){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }

常用方法2.0

        Integer[] arr = {1,2,5,8,6647};
        //binarySearch 通过二分搜索法进行查找,要求必须排好
        /**
         *1.使用binarySearch 二叉查找
         *2.要求该数组是有序的,如果该数组是无序的,不能使用binarySearch
         *3.如果数组中不存在要查找的数,则返回-(其应该插入的位置索引+1)
         * return -(low + 1);  // key not found.
         *
         */
        int index = Arrays.binarySearch(arr,1);
        int index2 = Arrays.binarySearch(arr,8);
        int index3 = Arrays.binarySearch(arr,10);
        System.out.println(index);//0
        System.out.println(index2);//3
        System.out.println(index3);//-5   -(10本应该插在4索引处,再+1) = -5

        //4.copyOf 数组元素的复制
        //从arr中拷贝arr.length长度的元素到newArr
        //如果拷贝的长度>arr.length 就在新数组的后面,增加null
        //拷贝0个,输出[] 拷贝-1个  抛出异常
        //该方法的底层使用的是 System.arraycopy();
        Integer[] newArr = Arrays.copyOf(arr, arr.length);
        System.out.println("拷贝完成后============");
        System.out.println(Arrays.toString(newArr));//[1, 2, 5, 8, 6647]
        Integer[] newArr2 = Arrays.copyOf(arr, arr.length+1);
        System.out.println(Arrays.toString(newArr2));//[1, 2, 5, 8, 6647, null]

        //5.fill 数组元素的扩充
        Integer[] num = new Integer[]{9, 3, 2};
        //使用99  去填充num数组,可以理解成是替换原来的元素
        Arrays.fill(num,99);
        System.out.println("num数组填充后================");
        System.out.println(Arrays.toString(num));//[99, 99, 99]


        //6.equals比较两个数组元素的内容是否完全一致
        //如果一样就返回true
        Integer[] arr2 = {1,2,5,8,6647};
        boolean equals = Arrays.equals(arr,arr2);
        System.out.println("equals==========="+equals);


        //7.asList将一组值,转换成List集合
        //返回的asList编译类型 List(接口)
        //asList运行类型java.util.Arrays$ArrayList  是Arrays类的静态内部类
//        private static class ArrayList<E> extends AbstractList<E>
//                implements RandomAccess, java.io.Serializable{...}
        List<Integer>  asList = Arrays.asList(2,3,4,5,6,1);
        System.out.println("asList="+asList);//asList=[2, 3, 4, 5, 6, 1]
        System.out.println("asList的运行类型"+asList.getClass());//java.util.Arrays$ArrayList

实践练习

在这里插入图片描述

//给定的数据对象如下
		   Book[] books = new Book[4];
            books[0] = new Book("红楼梦",100);
            books[1] = new Book("新金瓶梅",90);
            books[2] = new Book("青年文摘2020",5);
            books[3] = new Book("Java从入门到放弃",300);

//完整代码实现
//Book类
class Book{
        private String bookName;
        private double price;

        public Book(String bookName, double price) {
            this.bookName = bookName;
            this.price = price;
        }

        public Book() {
        }

        public String getBookName() {
            return bookName;
        }

        public void setBookName(String bookName) {
            this.bookName = bookName;
        }

        public double getPrice() {
            return price;
        }

        public void setPrice(double price) {
            this.price = price;
        }

        @Override
        public String toString() {
            return "Book{" +
                    "bookName='" + bookName + '\'' +
                    ", price=" + price +
                    '}';
        }
}
//main方法
public class Journey {
        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("青年文摘2020",5);
            books[3] = new Book("Java从入门到放弃",300);
            //1.实现按照价格从大到小排序
            Arrays.sort(books, new Comparator() {
                //这里是对Book数组排序,因此o1 和 o2就是Book对象
                @Override
                public int compare(Object o1, Object o2) {
                    //先转为Book类型
                    Book book1 = (Book) o1;
                    Book book2 = (Book) o2;
                    //这里之所以用double型的difference是因为compare要求了返回的是int类型,
                    //Arrays的sort方法在底层调用compare方法,其要求返回int,回顾之前的,深挖Arrays.sort源码,我们
                    //发现,其进入到了TimSort类的binarySort方法,在binarySort方法内部,会根据动态绑定机制执行c.compare
                    //其要求我们传入的是整数,所以如果直接将book2.getPrice()-book1.getPrice()传入就通不过了,因为类型不匹配
                    /**
                     * while (left < right) {
                     *    int mid = (left + right) >>> 1;
                     *    if (c.compare(pivot, a[mid]) < 0)
                     *        right = mid;
                     *    else
                     *        left = mid + 1;
                     * }
                     */
                    double difference = book2.getPrice()-book1.getPrice();//用一个double类型的引用来接收两数之差
       //以下这里进行了转换,根据差值来返回不同的整数,以满足既能符合重写compare的要求,
       //又不降低比较的要求(不改变用double类型来接收差值)
       //如果发现返回结果和预期相反,就修改调换下返回的1和-1
                    if(difference>0){
                        return 1;
                    }else if (difference < 0){
                        return -1;
                    }else {
                        return 0;
                    }
                }
            });
            System.out.println(Arrays.toString(books));
            /**
             * [Book{bookName='Java从入门到放弃', price=300.0}, Book{bookName='红楼梦', price=100.0},
             * Book{bookName='新金瓶梅', price=90.0}, Book{bookName='青年文摘2020', price=5.0}]
             */

            //2.实现价格从小到大排序
            Arrays.sort(books, new Comparator() {
                //这里是对Book数组排序,因此o1 和 o2就是Book对象
                @Override
                public int compare(Object o1, Object o2) {
                    //先转为Book类型
                    Book book1 = (Book) o1;
                    Book book2 = (Book) o2;

                    double difference = book2.getPrice()-book1.getPrice();//用一个double类型的引用来接收两数之差
                    //以下这里进行了转换,根据差值来返回不同的整数,以满足既能符合重写compare的要求,又不降低比较的要求(不改变用double类型来接收差值)
                    //如果发现返回结果和预期相反,就修改调换下返回的1和-1
                    if(difference>0){
                        //这里写-2,-3都行,因为深层次的源码,进入while循环,if (c.compare(pivot, a[mid]) < 0)这儿判断,只要求知道是大于0还是小于0
                        return -1;
                    }else if (difference < 0){
                        return  1;
                    }else {
                        return 0;
                    }
                }
            });
            System.out.println(Arrays.toString(books));
            /**
             * [Book{bookName='青年文摘2020', price=5.0}, Book{bookName='新金瓶梅', price=90.0},
             * Book{bookName='红楼梦', price=100.0}, Book{bookName='Java从入门到放弃', price=300.0}]
             */
            //按照书名的长度从大到小排序
            Arrays.sort(books, new Comparator() {
                //这里是对Book数组排序,因此o1 和 o2就是Book对象
                @Override
                public int compare(Object o1, Object o2) {
                    //先转为Book类型
                    Book book1 = (Book) o1;
                    Book book2 = (Book) o2;
                    //要求按照书名的长度来进行排序,此时的返回结果就是整数
                    return book2.getBookName().length()-book1.getBookName().length();

                }
            });
            System.out.println(Arrays.toString(books));
            /**
             * [Book{bookName='Java从入门到放弃', price=300.0}, Book{bookName='青年文摘2020', price=5.0},
             * Book{bookName='新金瓶梅', price=90.0}, Book{bookName='红楼梦', price=100.0}]
             */

        }
    }

实践练习2.0

/**
假设你有一个包含 Person 对象的数组,每个 Person 对象有三个属性:name(字符串),age(整数),和 height(浮点数)。你需要实现一个自定义排序功能,要求能够根据不同的排序条件对 Person 对象数组进行排序。
需求:
实现一个 Person 类,包含 name、age、height 三个属性,并提供合适的构造函数和 toString 方法。
实现一个 bubbleSort 方法,接收一个 Person[] 数组和一个 Comparator<Person> 接口,用于按照自定义排序规则对数组进行排序。
提供以下几种排序条件:
			按照 age 从小到大排序。
			按照 height 从大到小排序。
			按照 name 的字母顺序排序(不区分大小写)。
在 main 方法中:
创建几个 Person 对象并放入数组。
分别调用 bubbleSort 方法,实现上述三种排序,打印排序后的结果。
*/
import java.util.Arrays;
import java.util.Comparator;

public class Journey {
    public static void main(String[] args) {
        Person[] person = new Person[4];
        person[0] = new Person("Alice", 23, 165.5);
        person[1] = new Person("Bob", 30, 175.0);
        person[2] = new Person("Charlie", 28, 185.0);
        person[3] = new Person("Ali", 18, 170.0);
        //1.实现按照age从小到大排序
        BubbleSortPlus(person, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });
        System.out.println(Arrays.toString(person));

        /**
         * [Person{name='Ali', age=18, height=170.0}, Person{name='Alice', age=23, height=165.5},
         * Person{name='Charlie', age=28, height=185.0}, Person{name='Bob', age=30, height=175.0}]
         */

        //2.实现按照height从大到小排序
        BubbleSortPlus(person, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                double heightDifference = o1.getHeight() - o2.getHeight();
                if(heightDifference>0){
                    return -10;
                }else if (heightDifference<0){
                    return 10;
                }else {
                    return -2;//相等时交换与否没啥意义
                }
            }
        });
        System.out.println(Arrays.toString(person));
        /**
         *[Person{name='Charlie', age=28, height=185.0}, Person{name='Bob', age=30, height=175.0},
         *  Person{name='Ali', age=18, height=170.0}, Person{name='Alice', age=23, height=165.5}]
         */
        //3.按照name中的字母顺序排序
        BubbleSortPlus(person, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
            //思路1.逐个比较,取短串来做循环,如果不等,就返回此时的字符差值
            /*    // 逐字符比较,使用compareToIgnoreCase来忽略大小写差异
                int length1 = o1.getName().length();
                int length2 = o2.getName().length();
                int minLength = Math.min(length1, length2);

                for (int i = 0; i < minLength; i++) {
                    char char1 = o1.getName().charAt(i);
                    char char2 = o2.getName().charAt(i);
                    if (char1 != char2) {//=0的话,直接一边玩去
                        return char1 - char2;//>0,说明要交换才符合题意
                        //<0,说明符合题意,之后在compare那儿不会调换顺序
                    }
                }

                // 当一个字符串是另一个的前缀时,较短的字符串应排在前面  ABC   ABCD
                //比完ABC和ABCD的前三个字母,此时按理来说ABC应该排在前面,所以return负数,在compare那儿不交换
                return length1 - length2;*/
            //思路2.推荐使用,谁让你个憨憨忘掉了String的这个方法
                return o1.getName().compareToIgnoreCase(o2.getName());
            }
        });
        System.out.println(Arrays.toString(person));
        /**
         * [Person{name='Ali', age=18, height=170.0}, Person{name='Alice', age=23, height=165.5},
         * Person{name='Bob', age=30, height=175.0}, Person{name='Charlie', age=28, height=185.0}]
         */

    }
    public static void BubbleSortPlus(Person[] person, Comparator<Person> comparator){


        for(int e= person.length-1;e>0;e--){
            for(int i=0;i<e;i++){
                if(comparator.compare(person[i],person[i+1])>0){
                    Person temp = null;
                    temp = person[i];
                    person[i] = person[i+1];
                    person[i+1] = temp;
                }
            }
        }
    }
}

class Person {
    private String name;
    private int age;
    private double height;

    public Person(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    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 double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}

大数处理方案

        //当我们编程中,需要处理很大很大的整数,long不够用
        //可以使用BigInteger的类来搞定
//        long l = 238989329382930232099320;//报异常Integer number too large

        BigInteger bigInteger = new BigInteger("238989329382930232099320");
        BigInteger bigInteger2 = new BigInteger("10");
        System.out.println(bigInteger);//238989329382930232099320

        //1.在对BigInteger进行加减乘除的时候,需要使用相对应的方法,不能直接+-*/
        //  可以创建一个要操作的 BigInteger 然后进行相应的操作
        BigInteger addres = bigInteger.add(bigInteger2);
        System.out.println(addres);//238989329382930232099330
        BigInteger subres = bigInteger.subtract(bigInteger2);
        System.out.println(subres);//238989329382930232099310
        BigInteger mulres = bigInteger.multiply(bigInteger2);
        System.out.println(mulres);//2389893293829302320993200
        BigInteger divres = bigInteger.divide(bigInteger2);
        System.out.println(divres);//23898932938293023209932

        //当我们需要保存一个精度很高的数时,double不够用,会发生精度缩减
        //此时可以使用BigDecimal
        double d  = 199.111568999999999999999524;
        System.out.println(d);//199.111569
        BigDecimal bigDecimal = new BigDecimal("199.111568999999999999999524");
//           BigDecimal bigDecimal = new BigDecimal("199.11156");
        BigDecimal bigDecimal2 = new BigDecimal("0.1");
        System.out.println(bigDecimal);//199.111568999999999999999524

        //2.对BigDecimal进行加减乘除的时候,需要使用相对应的方法,不能直接+-*/
//          可以创建一个要操作的 BigDecimal 然后进行相应的操作
        BigDecimal Baddres = bigDecimal.add(bigDecimal2);
        System.out.println(Baddres);//199.211568999999999999999524
        BigDecimal Bsubres = bigDecimal.subtract(bigDecimal2);
        System.out.println(Bsubres);//199.011568999999999999999524
        BigDecimal Bmulres = bigDecimal.multiply(bigDecimal2);
        System.out.println(Bmulres);//19.9111568999999999999999524
        BigDecimal Bdivres = bigDecimal.divide(bigDecimal2);
        //相除时,有时可能会抛出异常,因为其可能是除不尽的,其保留的小数点精度极高的,
        // 如果除数此时是0.3,相除是个无限循环小数,会抛出异常如下
        //ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
        System.out.println(Bdivres);//1991.11568999999999999999524

        //如何解决相除时抛异常的情况呢?
        //在调用divide 方法时,指定精度即可  BigDecimal.ROUND_CEILING
        //如果有无限循环小数,其就会发挥作用,只保留到 分子 的精度
        //  即199.111568999999999999999524  有小数点后有几位,就保留到几位。
        //if 199.111568999999999999999524变成了199.11156  ,则输出的结果也会只保留小数点后5位
        //   此时输出了    663.70520
        BigDecimal bigDecimal3 = new BigDecimal("0.3");//新建一个不处理的话,会抛出异常的除数对象
        System.out.println(bigDecimal.divide(bigDecimal3,BigDecimal.ROUND_CEILING));//663.705229999999999999998414

应用场景

  • BigInteger适合保存比较大的整型
  • BigDecimal适合保存精度更高的浮点型

二者底层都是将大数当作字符串,之后再转成相应的对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值