Java数字操作类

大整数操作类:BigInteger

如果说现在要操作的数据值很大,那么首先想到的应该是double,那么如果说现在计算的结果超过了double会怎样。

public class TestDemo { public static void main(String args[]) { System.out.println(Doublic.MAX_VALUE * Doublic.MAX_VALUE); }}

输出结果

Infinity

现在发现此时的计算结果并不存在,因为已经超过了double的范畴。面试题:请问当前假设有两个很大的数字要进行数学计算(超过了doulble范围),你该怎么做?如果真的超过了double的范围,那么肯定无法使用double进行保存,只有String型才能保存。如果真的数据很大的数字要进行数学计算,只能够将其变为String型,而后按位取出每一个字符保存的数据,进行手工的计算。所以在Java里面考虑到了此类情况,专门提供了大数字的操作类,其中就有BigInteger、BigDecimal两种。

BigInteger类的构造方法:public BigInteger(String
val),它接收的是String型。

public class TestDemo { public static void main(String args[]) { BigInteger bigA = new BigInteger("124123412141234"); BigInteger bigB = new BigInteger("987654345"); System.out.println("加法操作:" + (bigA.add; System.out.println("减法操作:" + (bigA.subtract; System.out.println("乘法操作:" + (bigA.multiply; System.out.println("除法操作:" + (bigA.divide; // 数组里面只有两个元素,第一个元素表示的是商,第二个元素表示的是余数 BigInteger result[] = bigA.divideAndRemainder; System.out.println("商:" + result[0] + " 余数:" + result[1]); }}

输出结果

加法操作:124124399795579减法操作:124122424486889乘法操作:122591027317515513761730除法操作:125674商:125674 余数:939987704

在Java里面虽然提供了大数字的操作类,但是很多的时候,我们使用的项目开发可能对于数字要求会更加的敏感,这个时候Java本身所提供的数字类是帮助不大的。这个时候应该去找第三方的包。

         1、
ROUND_UP:远离零方向舍入。向绝对值最大的方向舍入,只要舍弃位非0即进位。

成员变量:

  • public static final double PI
  • public static final double E

数学操作类的使用,其中BigInteger、BigDecimal可以操作大数字。最下面是重点,实现准确的四舍五入操作。

         11.545 = 11.54 —–五后无数,若前位为偶数应舍去

正则表达式的组成规则

  • 规则字符在java.util.regex Pattern类中

Random类

这个类的主要功能是取得随机数的操作类。

范例:产生10个不大于100的正整数

public class TestDemo { public static void main(String args[]) { Random rand = new Random(); for(int i = 0; i < 10; i++) { System.out.print(rand.nextInt + "、"); } }}

输出结果可能为

53、31、77、51、68、23、59、63、27、93、

这样,计算double类型的数据计算问题就可以处理了。 
另外补充一下 JavaScript 四舍五入的方法: 
小数点问题  

Random类成员方法

  • public int nextInt(): 返回Int范围内的随机数
  • public int nextInt(int n):返回的是[0,n)范围内的随机数。

public class RandomDemo {
    public static void main(String[] args) {
        // 创建对象
        // Random r = new Random();
        Random r = new Random(1111);

        for (int x = 0; x < 10; x++) {
            // int num = r.nextInt();
            int num = r.nextInt(100) + 1;
            System.out.println(num);
        }
    }
}

Math类

Math就是一个专门进行数学计算的操作类,里面提供了一系列的数学计算方法。在Math类里面提供的一切方法都是static型的方法,因为Math类里面没有普通属性。

Math有一个方法要引起注意:四舍五入:public static long
round。范例:观察四舍五入

public class TestDemo { public static void main(String args[]) { System.out.println(Math.round; System.out.println(Math.round; System.out.println(Math.round; }}

输出结果

16-15-16

如果进行负数四舍五入的时候,操作的数据小数位大于0.5才进位,小于等于0.5不进位。

         11.556 = 11.56 ——六入

成员方法

  • public final String format(Date date) :格式化:Data –> String
  • public Date parse(String source):解析:String –> Data

public class DateFormatDemo {
    public static void main(String[] args) throws ParseException {
        // Date -- String
        // 创建日期对象
        Date d = new Date();
        // 创建格式化对象
        // SimpleDateFormat sdf = new SimpleDateFormat();
        // 给定模式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        // public final String format(Date date)
        String s = sdf.format(d);
        System.out.println(s);


        //String -- Date
        String str = "2008-08-08 12:12:12";
        //在把一个字符串解析为日期的时候,请注意格式必须和给定的字符串格式匹配
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date dd = sdf2.parse(str);
        System.out.println(dd);
    }
}

/*
运行结果:
2016年03月09日 23:29:35
Fri Aug 08 12:12:12 CST 2008
*/
  • Math类
  • Random类
  • 大数字操作类

Output:
12.5的四舍五入值:13
-12.5的四舍五入值:-12

Math类概述

  • Math
    类包含用于执行基本数学运算的方法,如初等指数对数平方根三角函数

大浮点数操作类:BigDecimal

BigInteger
不能够保存小数,而BigDecimal可以保存小数数据。在BigDecimal里提供有如下几种构造:

  • 构造一:public BigDecimal(String val)。
  • 构造二:public BigDecimal(double val)。

与BigInteger一样,BigDecimal本身也支持基础的数学计算,可是使用BigDecimal还有一个非常重要的目的,就是可以使用它来实现准确的四舍五入操作。

之前使用的Math.round()实现四舍五入操作,但是这种操作有一个问题,所有的小数位都四舍五入了。遗憾的是BigDecimal类里面没有直接提供有四舍五入的操作支持,可是可以利用除法实现:

  • 除法操作:public BigDecimal divide(BigDecimal divisor, int scale,
    int roundingMode)。

    • BigDecimal divisor:被除数。
    • int scale:保留的小数位。
    • int roundingMode:进位模式(public static final int
      ROUND_HALF_UP)。

范例:实现准确的四舍五入

public class MyMath { /** * 实现准确位数的四舍五入操作 * @param num 要进行四舍五入操作的数字 * @param scale 要保留的小数位 * @return 处理后的四舍五入数据 */ public static double round(double num, int scale) { BigDecimal bigA = new BigDecimal; BigDecimal bigB = new BigDecimal; return bigA.divide(bigB, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); }}public class TestDemo { public static void main(String args[]) { System.out.println(MyMath.round(19.783231231, 2)); System.out.println(MyMath.round); System.out.println(MyMath.round; }}

输出结果

19.78-1616

此类操作的功能在日后的开发之中一定要会使用,属于工具类的支持范畴。

  • Math类重要要清楚round()方法的坑。
  • Random类生成随机数。
  • 如果数据量大就使用BigInteger或BigDecimal,这两个类是Number的子类。

更多内容戳这里

      提到四舍五入那么保留位就必不可少了,在java运算中我们可以使用多种方式来实现保留位。

概述及基本使用

  • 正则表达式:是指用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。

  • QQ号判断:

public static boolean checkQQ(String qq) {
    // String regex ="[1-9][0-9]{4,14}";
    // //public boolean matches(String regex)告知此字符串是否匹配给定的正则表达式
    // boolean flag = qq.matches(regex);
    // return flag;

    //return qq.matches("[1-9][0-9]{4,14}");

    return qq.matches("[1-9]\d{4,14}");
}

BigDecimal
在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用
java.math.BigDecimal。BigDecimal一共有4个够造方法,我们不关心用BigInteger来够造的那两个,那么还有两个,
它们是:
BigDecimal(double val) 
          Translates a double into a BigDecimal. 
BigDecimal(String val) 
          Translates the String repre sentation of a BigDecimal into a BigDecimal.
上面的API简要描述相当的明确,而且通常情况下,上面的那一个使用起来要方便一些。我们可能想都不想就用上了,会有什么问题呢?等到出了问题的时候,才发现上面哪个够造方法的详细说明中有这么一段:
Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding. 
The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(“.1”) is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one.
原来我们如果需要精确计算,非要用String来够造BigDecimal不可!在《Effective Java》一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,这也许是一个小小的失误吧。
 
解决方案
现在我们已经可以解决这个问题了,原则是使用BigDecimal并且一定要用String来够造。
但是想像一下吧,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另
一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?下面我们提供一个工具类Arith来简化操作。它
提供以下静态方法,包括加减乘除和四舍五入:
public static double add(double v1,double v2)
public static double sub(double v1,double v2)
public static double mul(double v1,double v2)
public static double div(double v1,double v2)
public static double div(double v1,double v2,int scale)
public static double round(double v,int scale)

Math类

         5、 HALF_UP:最近数字舍入(5进)。这是我们最经典的四舍五入。

[TOC]

四舍五入是我们小学的数学问题,这个问题对于我们程序猿来说就类似于1到10的加减乘除那么简单了。在讲解之间我们先看如下一个经典的案例:

构造方法

  • public Date():根据当前的默认毫秒值创建日期对象。
  • public Date(long date):根据给定的毫秒值创建日期对象。

public class DateDemo {
    public static void main(String[] args) {
        // 创建对象
        Date d = new Date();
        System.out.println("d:" + d);

        // 创建对象
        // long time = System.currentTimeMillis();
        long time = 1000 * 60 * 60; // 1小时
        Date d2 = new Date(time);
        System.out.println("d2:" + d2);
        //d2:Thu Jan 01 09:00:00 CST 1970
        //东方时区8+1H
    }
}

在使用Java,double
进行运算时,经常出现精度丢失的问题,总是在一个正确的结果左右偏0.0000**1。
特别在实际项目中,通过一个公式校验该值是否大于0,如果大于0我们会做一件事情,小于0我们又处理其他事情。
这样的情况通过double计算出来的结果去和0比较大小,尤其是有小数点的时候,经常会因为精度丢失而导致程序处理流程出错。

DateFormat类概述

  • DateFormat
    是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间
  • 因为是抽象类,所以使用其子类SimpleDateFormat
    • 格式化:Data –> String
    • 解析:String –> Data

      下面实例是使用银行家舍入法:

Date类及DateFormat类练习

  • 制作一个工具类。DateUtil
    • DataUtil

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 这是日期和字符串相互转换的工具类
 * 
 * @author 风清扬
 */
public class DateUtil {
    private DateUtil() {
    }

    /**
     * 这个方法的作用就是把日期转成一个字符串
     * 
     * @param d
     *            被转换的日期对象
     * @param format
     *            传递过来的要被转换的格式
     * @return 格式化后的字符串
     */
    public static String dateToString(Date d, String format) {
        // SimpleDateFormat sdf = new SimpleDateFormat(format);
        // return sdf.format(d);
        return new SimpleDateFormat(format).format(d);
    }

    /**
     * 这个方法的作用就是把一个字符串解析成一个日期对象
     * 
     * @param s
     *            被解析的字符串
     * @param format
     *            传递过来的要被转换的格式
     * @return 解析后的日期对象
     * @throws ParseException
     */
    public static Date stringToDate(String s, String format)
            throws ParseException {
        return new SimpleDateFormat(format).parse(s);
    }
}
  • DataUtilDemo

import java.text.ParseException;
import java.util.Date;

/*
 * 工具类的测试
 */
public class DateUtilDemo {
    public static void main(String[] args) throws ParseException {
        Date d = new Date();
        // yyyy-MM-dd HH:mm:ss
        String s = DateUtil.dateToString(d, "yyyy年MM月dd日 HH:mm:ss");
        System.out.println(s);

        String s2 = DateUtil.dateToString(d, "yyyy年MM月dd日");
        System.out.println(s2);

        String s3 = DateUtil.dateToString(d, "HH:mm:ss");
        System.out.println(s3);

        String str = "2014-10-14";
        Date dd = DateUtil.stringToDate(str, "yyyy-MM-dd");
        System.out.println(dd);
    }
}
  • 算一下你来到这个世界多少天?

/*
 * 算一下你来到这个世界多少天?
 * 
 * 分析:
 *         A:键盘录入你的出生的年月日
 *         B:把该字符串转换为一个日期
 *         C:通过该日期得到一个毫秒值
 *         D:获取当前时间的毫秒值
 *         E:用D-C得到一个毫秒值
 *         F:把E的毫秒值转换为年
 *             /1000/60/60/24
 */
public class MyYearOldDemo {
    public static void main(String[] args) throws ParseException {
        // 键盘录入你的出生的年月日
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你的出生年月日:");
        String line = sc.nextLine();

        // 把该字符串转换为一个日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d = sdf.parse(line);

        // 通过该日期得到一个毫秒值
        long myTime = d.getTime();

        // 获取当前时间的毫秒值
        long nowTime = System.currentTimeMillis();

        // 用D-C得到一个毫秒值
        long time = nowTime - myTime;

        // 把E的毫秒值转换为年
        long day = time / 1000 / 60 / 60 / 24;

        System.out.println("你来到这个世界:" + day + "天");
    }
}

         11.555 = 11.56 —–五后无数,若前位为奇数应进位

Random类概述

  • 此类用于产生随机数
  • 如果用相同的种子创建两个 Random
    实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。

      舍去位的数值大于5时,进位后舍去。

判断功能(String 类)
  • public boolean matches(String regex)
  • 手机号码练习:

public class PhoneNumber {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Pleas input you phonenumber:");
        String phone = sc.nextLine();

        String regex = "1[38]\d{9}";
        boolean flag = phone.matches(regex);
        System.out.println("The Phone Number is:"+flag);
    }
}
  • 邮箱验证:

public class RegexTest {
    public static void main(String[] args) {
        //键盘录入邮箱
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入邮箱:");
        String email = sc.nextLine();

        //定义邮箱的规则
        //String regex = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]{2,6}(\.[a-zA-Z_0-9]{2,3})+";
        String regex = "\w+@\w{2,6}(\.\w{2,3})+";

        //调用功能,判断即可
        boolean flag = email.matches(regex);

        //输出结果
        System.out.println("flag:"+flag);
    }
}

 

分割功能(String 类)
  • public String[] split(String regex)

  • 练习1:

public class RegexDemo {
    public static void main(String[] args) {
        //定义一个年龄搜索范围
        String ages = "18-24";

        //定义规则
        String regex = "-";

        //调用方法
        String[] strArray = ages.split(regex);

        //如何得到int类型的呢?
        int startAge = Integer.parseInt(strArray[0]);
        int endAge = Integer.parseInt(strArray[1]);

        //键盘录入年龄
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你的年龄:");
        int age = sc.nextInt();

        if(age>=startAge && age<=endAge) {
            System.out.println("你就是我想找的");
        }else {
            System.out.println("不符合我的要求,gun");
        }
    }
}
  • 练习2:

public class RegexDemo2 {
    public static void main(String[] args) {
        // 定义一个字符串
        String s1 = "aa,bb,cc";
        // 直接分割
        String[] str1Array = s1.split(",");
        for (int x = 0; x < str1Array.length; x++) {
            System.out.println(str1Array[x]);
        }
        System.out.println("---------------------");

        String s2 = "aa.bb.cc";
        String[] str2Array = s2.split("\.");
        for (int x = 0; x < str2Array.length; x++) {
            System.out.println(str2Array[x]);
        }
        System.out.println("---------------------");

        String s3 = "aa    bb                cc";
        String[] str3Array = s3.split(" +");
        for (int x = 0; x < str3Array.length; x++) {
            System.out.println(str3Array[x]);
        }
        System.out.println("---------------------");

        //硬盘上的路径,我们应该用\替代
        String s4 = "E:\JavaSE\day14\avi";
        String[] str4Array = s4.split("\\");
        for (int x = 0; x < str4Array.length; x++) {
            System.out.println(str4Array[x]);
        }
        System.out.println("---------------------");
    }
}
  • 练习3:

/*
 * 我有如下一个字符串:"91 27 46 38 50"
 * 请写代码实现最终输出结果是:"27 38 46 50 91"
 * 
 * 分析:
 *         A:定义一个字符串
 *         B:把字符串进行分割,得到一个字符串数组
 *         C:把字符串数组变换成int数组
 *         D:对int数组排序
 *         E:把排序后的int数组在组装成一个字符串
 *         F:输出字符串
 */
public class RegexTest {
    public static void main(String[] args) {
        // 定义一个字符串
        String s = "91 27 46 38 50";

        // 把字符串进行分割,得到一个字符串数组
        String[] strArray = s.split(" ");

        // 把字符串数组变换成int数组
        int[] arr = new int[strArray.length];

        for (int x = 0; x < arr.length; x++) {
            arr[x] = Integer.parseInt(strArray[x]);
        }

        // 对int数组排序
        Arrays.sort(arr);

        // 把排序后的int数组在组装成一个字符串
        StringBuilder sb = new StringBuilder();
        for (int x = 0; x < arr.length; x++) {
            sb.append(arr[x]).append(" ");
        }
        //转化为字符串
        String result = sb.toString().trim();

        //输出字符串
        System.out.println("result:"+result);
    }
}

         7、 HAIL_EVEN:银行家舍入法。

成员方法

  • public static Calendar getInstance():获得一个日历对象
  • public int get(int field):根据日历字段得到对应的值。
    • 返回给定日历字段的值。日历类中的每个日历字段都是静态的成员变量,并且是int类型。
  • public void add(int field,int amount)
    • 根据日历字段和一个正负数确定是添加还是减去对应日历字段的值。
  • public final void set(int year,int month,int date)
    • 设置日历对象的年月日

import java.util.Calendar;

/*
 * Calendar:它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
 * 
 * public int get(int field):返回给定日历字段的值。日历类中的每个日历字段都是静态的成员变量,并且是int类型。
 */

public class CalendarDemo {
    public static void main(String[] args) {
        // 其日历字段已由当前日期和时间初始化:
        Calendar rightNow = Calendar.getInstance(); // 子类对象//多态用法。

        // 获取年
        int year = rightNow.get(Calendar.YEAR);
        // 获取月
        int month = rightNow.get(Calendar.MONTH);
        // 获取日
        int date = rightNow.get(Calendar.DATE);

        System.out.println(year + "年" + (month + 1) + "月" + date + "日"); //month从0开始
    }
}

/*
 * abstract class Person { public static Person getPerson() { return new
 * Student(); } }
 * 
 * class Student extends Person {
 * 
 * }
 */



import java.util.Calendar;

/*
 * public void add(int field,int amount):根据给定的日历字段和对应的时间,来对当前的日历进行操作。
 * public final void set(int year,int month,int date):设置当前日历的年月日
 */
public class CalendarDemo {
    public static void main(String[] args) {
        // 获取当前的日历时间
        Calendar c = Calendar.getInstance();

        // 获取年
        int year = c.get(Calendar.YEAR);
        // 获取月
        int month = c.get(Calendar.MONTH);
        // 获取日
        int date = c.get(Calendar.DATE);
        System.out.println(year + "年" + (month + 1) + "月" + date + "日");

        // // 三年前的今天
        // c.add(Calendar.YEAR, -3);
        // // 获取年
        // year = c.get(Calendar.YEAR);
        // // 获取月
        // month = c.get(Calendar.MONTH);
        // // 获取日
        // date = c.get(Calendar.DATE);
        // System.out.println(year + "年" + (month + 1) + "月" + date + "日");

        // 5年后的10天前
        c.add(Calendar.YEAR, 5);
        c.add(Calendar.DATE, -10);
        // 获取年
        year = c.get(Calendar.YEAR);
        // 获取月
        month = c.get(Calendar.MONTH);
        // 获取日
        date = c.get(Calendar.DATE);
        System.out.println(year + "年" + (month + 1) + "月" + date + "日");
        System.out.println("--------------");

        c.set(2011, 11, 11);
        // 获取年
        year = c.get(Calendar.YEAR);
        // 获取月
        month = c.get(Calendar.MONTH);
        // 获取日
        date = c.get(Calendar.DATE);
        System.out.println(year + "年" + (month + 1) + "月" + date + "日");
    }
}

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website