包装类(封装类)

java中所有的东西,都能看做面向对象。其中八个基本类型不在其中,它们违背了面向对象的基本概念。所以,java开发者写了一些类,用于把这几个基本类型包装成类。很早就有了,包装了8个基本类型。这样就可以使用类的一些特性。

Application Programming Interface 应用程序编程接口,一些预先创建好的类以及方法,目的是为了让我们更好进行程序开发。

有专业的文档(API)。去官网下载就行了

  • byte—Byte
  • short—Short
  • Int—Integer 最常用的就是Integer
  • long—Long
  • float—Float 这个也用的多
  • double—Double 这个也会用
  • char—Character
  • boolean—Boolean
  1. 类所在的包。java.lang 包。long是一个类型,java.lang是一个包名
    • 八个包装类都在同一个包下,java.lang包下,不需要import导包直接使用。
    • 八个包装类中有六个是与数字相关,都默认继承一个父类 Number类
    • 八个包装类都实现了Serializable, Comparable[Integer](https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html)
    • 每一个类中的构造方法。
    • 八个包装类都有带自己对应类型参数的构造方法。
      • 八个包装类中有七个还有构造方法重载。除了Character,带String类型的重载。new Integer(10;new Integer(10)
    • 创建对象,对象调用属性/方法
      • new integer(“abc”)—->NumberFormatException。
      • JDK1.5之后,自动拆装。自动可以把一个包装类拆成基本类型,也可以自动把一个基本类型包装成一个包装类。他们之前的转化没那么重要了。
      • 有六个与数字相关的类都继承Number。xxxValue(); intValue(),longValue()… 将一个包装类类型转化为对应的基本类型。相当于是拆包。 ```java Integer i1 = new Integer(10); // 把一个基本类型包装成包装类。 i1.intValue(); // 把一个i1的包装类拆分成一个基本类型。

Integer i2 = 10; // 把一个基本类型自动包装成包装类。JDK 1.5之后 int value = new Integer(10);// 把一个包装类自动拆分成基本类型。现在基本上没什么用了。

int value = Integer.parseInt(“123”); // 可以通过这样转化。 int value = new Integer(“123”); // 也能这样转化。

Float f = Float.parseFloat(“123.123”)

// 六个数字的包装类都能这样写。

  1. - 笔试中出现的问题
  2. ```java
  3. Integer i1 = 10;
  4. Integer i2 = 10;
  5. Integer i3 = new Integer(10);
  6. Integer i4 = new Integer(10);
  7. System.out.println(i1 == i2); // true
  8. System.out.println(i1 == i3); // false
  9. System.out.println(i3 == i4); // false
  10. System.out.println(i1.equals(i2)); // true
  11. System.out.println(i1.equals(i3)); // true
  12. System.out.println(i3.equals(i4)); // true

上面的问题的解答:

  1. i1表示存在Integer类中静态元素区的,所以,i1和i2的值是一样的。表示静态的里面的一个Integer对象。
  2. i3和i4表
  3. 示new产生的一个在堆内存里面的对象。每次产生的对象是不一样的。里面有很多方法,里面的private int value = 10;表示这个属性。
  4. equals方法,在Integer类中进行了重写。比较的是两个Integer里面存的具体的值。
    1. public boolean equals(Object obj) {
    2. if (obj instanceof Integer) {
    3. return value == ((Integer)obj).intValue();
    4. }
    5. return false;
    6. }
    注意:如果把i1改成1000,那么第一个打印为false。
    原因:在Integer类加载时,在Integer的内部空间有一个Integer[]-128~127范围个对象。也就是如果这个缓存的数组里面有,那么就直接用之前的缓存的值。如果没有,就给你new一个。
    考察的Integer类加载的时候,有一个内部类(如下),内部类里面有静态块执行。

静态块加载一个Integer类型的数组,里面存储256个Integer对象,-128~127,如果我们用的对象范围在这之内,直接取静态区中找对应的对象。如果赋值的值大于127,就会重新赋值。
源码如下:

  1. // 这是Integer类中的valueOf方法。判断就是根据上面的结果来的。
  2. public static Integer valueOf(int i) {
  3. if (i >= IntegerCache.low && i <= IntegerCache.high)
  4. return IntegerCache.cache[i + (-IntegerCache.low)];
  5. return new Integer(i);
  6. }
  7. // 这是Integer类重写的equals方法。如果是Integer方法或者是它的子类,判断的就是valueOf方法。
  8. public boolean equals(Object obj) {
  9. if (obj instanceof Integer) {
  10. return value == ((Integer)obj).intValue();
  11. }
  12. return false;
  13. }
  14. // 这是内部的静态类
  15. private static class IntegerCache {
  16. static final int low = -128;
  17. static final int high;
  18. static final Integer cache[];
  19. static {
  20. // high value may be configured by property
  21. int h = 127;
  22. String integerCacheHighPropValue =
  23. sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
  24. if (integerCacheHighPropValue != null) {
  25. try {
  26. int i = parseInt(integerCacheHighPropValue);
  27. i = Math.max(i, 127);
  28. // Maximum array size is Integer.MAX_VALUE
  29. h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
  30. } catch( NumberFormatException nfe) {
  31. // If the property cannot be parsed into an int, ignore it.
  32. }
  33. }
  34. high = h;
  35. cache = new Integer[(high - low) + 1];
  36. int j = low;
  37. for(int k = 0; k < cache.length; k++)
  38. cache[k] = new Integer(j++);
  39. // range [-128, 127] must be interned (JLS7 5.1.7)
  40. assert IntegerCache.high >= 127;
  41. }
  42. private IntegerCache() {}
  43. }

数学相关

Math

  1. 所属的包java.lang
  2. Math的构造方法是私有的。我们不能直接调用创建对象。
  3. 由于Math中提供的属性及方法都是static,不需要创建对象。
  4. 常用的方法:
    1. abs()返回数字的绝对值的。参数(int,long,float,double
    2. ceil()向上取整。返回的值是一个double类型。参数(int,long,float,double
    3. floor()向下取整。返回的值是一个double类型。参数(int,long,float,double
    4. rint()取离它最近的整数,如果都相差0.5,那就取偶数的。返回值是一个double类型。参数(int,long,float,double
    5. round()四舍五入。返回的类型是整数,long类型。参数(int,long,float,double
    6. min(a,b)两个数去最小的那个。参数(int,long,float,double)。但是参数a,b的类型必须一样。
    7. max(a,b)a和b两个数取最大的那个。参数同上min方法。
    8. pow(a,b)a的b次方(参数double,返回值也是double)
    9. sqrt(double a)获取给定参数的平方根
    10. random()随机产生一个[0,1)的数。返回值是double类型。

      随堂练习

      ```java // 随机产生[0,9)的随机整数 int value = (int)(Math.random() * 10);

// 随机产生[5.0,10.9)的随机小数。下面是错误演示 double value1 = (Math.random() * 6) + 5.0;

  1. **使用`Math.random(`)进行小数的操作可能会丢失一部分精度。**
  2. 原因:假如按照**例子2**的进行计算。那么`Math.random()`产生的数的范围是**[0.000...,0.9999...)**之间,那么乘以6之后,产生的范围就是**[0.000...,5.999...4)**。再加上**5.0**也打不到**10.9**的范围。最终的范围只在**[0.00010.999...4 )**之间。所以,对于小数进行随机取数来说,用`Math.random()`得到的结果并不精确,会有精度的丢失。
  3. **上述问题的解决方法:使用**`**Random**`**类**
  4. <a name="cwnwE"></a>
  5. ### Random类
  6. 1. 所属的包 java.util包中的,需要:`**import **``**java.util.Random**``**;**`
  7. 1. 没有任何的继承关系,默认继承**Object**类。
  8. 1. 查找构造方法:
  9. 1. `**[Random](https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#Random--)**``()`Creates a new random number generator.(返回一个新的随机数的生成器。)
  10. 1. **`[Random](https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#Random-long-)(long seed)`**`Creates a new random number generator using a single long seed.(随机产生一个新的随机数的生成器,使用单一的long类型。)。`一般不会用。
  11. 4. 一些常用的方法:先要得到一个**Random**对象
  12. 1. **`r.nextInt(int bound?);`**没有参数的话,返回值的范围就是**int**类型的范围的整数。如果有参数,那么返回值的范围就是`[0,bound)`的整数。**注意:****bound**必须是整数,如果写成负数,那么会报异常。异常为:`java.lang.IllegalArgumentException`(非法的参数异常)。如果想要产生负数的随机整数,那么产生的值减去**bound**的值就行。
  13. 1. **`r.nextFloat();`**没有参数。得到的数的范围是`[0.0,1.0)`的左闭又开的**float**类型的小数。
  14. 1. `[5.0,11.0)`的随机小数。**`r.nextInt(6)+5+r.nextFloat();`**整数的随机用整数的随机方法,小数的随机用小数的随机方法。
  15. 3. **`r.nextBoolean();`**产生随机的布尔值。true或者false
  16. ```java
  17. Random rd = new Random();
  18. int i = rd.nextInt(100);
  19. System.out.println(i);
  20. float f = rd.nextFloat();
  21. System.out.println(f);
  22. boolean b = rd.nextBoolean();
  23. System.out.println(b);

UUID类

  1. 所属的包java.util包中。
  2. 没有任何的继承关系,默认继承Object
  3. 构造方法有,但是没有无参数的构造方法。所以,我们通常不会创建对象。

    1. UUID uuid = UUID.randomUUID();
    2. System.out.println(uuid); // uuid是对象,重写了toString。产生的是32位的16进制的数字的字符串。一般用于数据库作为主键。重复的可能性非常的小。

    BigInteger类

    long 类型的范围-2的63次方~2的63次方减一。如果需要的数据的范围大于long类型。 底层用的是一个动态的数组。数字拆成一个一个的。

  4. 所属的包java.math

  5. 继承Number类。
  6. 如果创建对象。提供的构造方法全部都是带参数的,我们通常会利用带String参数的构造方法创建这个类的对象。参数就是很大的整数的字符串。
  7. 类中的常用的方法:做四则运算
    1. add``(BigInteger val)加方法
    2. subtract(BigInteger val)减方法
    3. multiply(BigInteger val)乘法
    4. divide(bigInteger val)除方法
    5. …还有什么绝对值啊,次方运算啊。
  8. 小例子:设计一个方法,用来计算给定数字的阶乘。

    1. public BigInteger factorial(long num) {
    2. BigInteger result = new BigInteger("1");
    3. for (int i = 1; i <= num; i++) {
    4. result = result.multiply(new BigInteger(i + ""));
    5. }
    6. return result;
    7. }

    BigDecima类

    超过了double的取值范围的小数用这个类。

  9. 所属的包:**java.math**

  10. 继承Number类。
  11. 构造方法很多很多。有String,Int,Double等类型的参数。
  12. 常用的方法同**BigInteger**类的方法。除了四则运算以外,还有处理小数点位数的方法。

    1. **setScale();**参数第一位,表示取几位小数。第二个参数表示取小数的方式。down表示向下取整。
      1. BigDecimal dc = new BigDecimal("123.234213523613135135134134134143");
      2. BigDecimal dc1 = dc.setScale(5, BigDecimal.ROUND_DOWN);
      3. System.out.println(dc1);

      DecimalFormat

      住专门用来处理Decimal的数据的格式化。这个的好处就是:可以将小数点之前和之后的位数都能处理。上面的BigDecima类里面的方法只能处理小数点之后的数字。上面的好处就是可以有很多处理小数的模式,向下或者向上等。但是这个只能四舍五入。

  13. 所属的包:java.text包。

  14. 构造方法的参数表示格式化的方式。0表示必须,#表示可有可无。
    1. // 0表示必须的,#表示可有可无,有的话就按照四舍五入。前面的不够的话,填0
    2. DecimalFormat df = new DecimalFormat("000.###");
    3. String value = df.format(23.1235134); // 返回值是String类型。
    4. System.out.println(value); // 023.124