java学习-java.lang一Number类

java.lang包是java语言中被用于编程的基本包。编写的程序基本上都要用到这个包内的常用类。

包含了基本数据类型包装类(Boolean,Number,Character,Void)以及常用类型类(String,StringBuilder,StringBuffer)

 

Number类    是所有数值类的父类,其直接子类

AtomicIntegerAtomicLongBigDecimalBigIntegerByteDoubleFloatIntegerLongShort

一、Integer类    int整型的包装类

数值范围(-231~~231-1)      这是64位的jdk,,占用4字节,最大长度为32位

主要以下部分内容

  • Integet类生成整型对象的静态方法    也就是将字符串转换成整型
  • Integer对象转换成字符串的方法。
  • Integer类的equals(Object obj)和toString()方法
  • Comparable<Integer>接口方法的实现

生成Integer对象方法

public static Integer valueOf(String s)或者public static Integer valueOf(String s, int radix)

这两个方法都是将字符串转换成整型对象,

Integer.valueOf("123")和Integer.valueOf("123",10)这方法是等同了,不带radix参数时,默认指定s的值是十进制数据,即radix=10

而如果s的值不是十进制数据时则要调用valueOf(String s, int radix)方法,要指定该字符串是多少进制数据。

  如Integer.valueOf("abc",16)     指定字符串"abc"  是十六进制数据

这将会返回一个数值为2748的Integer对象,也就是10*162+11*161+12*160=2748  

 

valueOf()方法直接调用了,public static int parseInt(String s, int radix)  ,将字符串解析成整型,

可以代表整型数据的字符,0-9     a-z   A-Z    这些数据可以表示整型数据,如果字符串中包含其它字符,则会发生异常。

a-z和A-Z,其实表示的是同一整型数据,a和A  一样表示10,b和B表示11

note:

  十六进制  字母范围为只能A-F ,因为十六进制单个字符能够表示的数值为16,满16进1

      如果执行语句

      parseInt("G",16)

    这会报错  java.lang.NumberFormatException: For input string: "G"

  指定的进制数不能解析这个字符串

/**
     * All possible chars for representing a number as a String
     */
    final static char[] digits = {
        '0' , '1' , '2' , '3' , '4' , '5' ,
        '6' , '7' , '8' , '9' , 'a' , 'b' ,
        'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
        'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
        'o' , 'p' , 'q' , 'r' , 's' , 't' ,
        'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    };

Integer对象转换成字符串的方法

Integer类内部有一些静态方法,用于将整型转换为字符串类型,

        String hexString = Integer.toHexString(50);//整型转换为16进制字符串
        String binaryString = Integer.toBinaryString(50);//二进制
        String decimalString = Integer.toString(50);//默认十进制
        String octalString = Integer.toOctalString(50);//八进制
        String otherString = Integer.toString(50, 27);//任意进制,这里为27进制,进制范围为:2~36
        System.out.println(hexString);
        System.out.println(binaryString);
        System.out.println(decimalString);
        System.out.println(octalString);
        System.out.println(otherString);

输出结果为

10
32
110010
50
62
1n

整型数据转换成字符串用这个没什么问题,但是负数转换成字符串的时候出现了很多问题

除了

Integer.toString(int i)
Integer.toString(int i, int radix)
这两个方法的正负整数转换成字符串只是在前面加一个负号。其他的暂时看不懂,不纠结
10
ffffffce
11111111111111111111111111001110
-50
37777777716
-1n

Integer类的equals(Object obj)和toString()方法

Integer类中重写了继承自Object类的equals(Object obj)方法,

Object类中的equals(Object obj )

public boolean equals(Object obj) {
        return (this == obj);
    }

由于==这个运算符是判断两个对象引用的内存地址是否相等,相等,表示两个object其实引用的是同一内存地址,同一对象。

 

Integer.equals(Object obj)

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

重写的equals()方法,如果对象不是Integer类型,返回false,如果是Integer类型,在判断对象的值是否相等。所以要比较两个整型对象的值是否相等,可以使用equals()方法进行比较

 

Integer.toString(),,也是重写了Object的toString()方法,返回了是Integer对象的值

Object.toString()
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

Integer.toString()
public String toString() { return toString(value); } public static String toString(int i) { if (i == Integer.MIN_VALUE) return "-2147483648"; int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); char[] buf = new char[size]; getChars(i, size, buf); return new String(buf, true); }

 Object的toString()是返回 字符串格式:  “类名@16进制的哈希值”,

以后要谨慎使用toString()方法了。

Comparable<Integer>接口方法的实现,对象列表的升序降序接口

我们通过重写改接口方法,可以对列表进行升序或降序排列。

Number类的实现类,也就是基本数据类型的包装类Integer, Float, Double,Long,Byte等都实现的Comparable接口,

  默认就可以调用List或者array的排序方法进行升序或降序排序。

 

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.

此接口对实现它的每个类的对象强加一个总排序。这种排序被称为类的自然排序,类的compareTo方法被称为其自然比较方法。

Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort).  

只有实现的这个接口的对象list列表或array数组才可以使用sort方法让列表或数组的元素被自动排序

 

只需要实现compareTo()方法即可

public int compareTo(){}这个比较方法,,
如果要将对象列表进行升序排序,则第i个元素和第i+1元素 要满足a[i]>a[i+1] 返回1 a[i]<a[i+1] 返回-1 a[i]=a[i+1] 返回0

如果要将对象列表进行降序排序  要满足 a[i]>a[i+1] 返回-1 a[i]<a[i+1] 返回1 a[i]=a[i+1] 返回0
Collections.sort方法实现的就是按照此比较的东西排列
升序(从小到大):
if(price < o.price){
    return -1;
}
if(price > o.price){
   return 1;
}
降序(从大到小):
if(price < o.price){
   return 1;
}
if(price > o.price){
   return -1;
}
    //将对象按价格进行升序排序
    @Override
    public int compareTo(flower o) {
        //首先比较price,如果price相同返回0
        if(price < o.price){
            return -1;
        }
        if(price > o.price){
            return 1;
        }
        
        return 0;
    }

 

为什么升序  返回值为1时,是n的值要大于n+1的值,而返回值为-1时n的值要小于n+1呢?

这个要查看源码才可以知道原理。(不好奇的可以不看哦^~^)

 

由于这个List.sort()这个排序方法时使用二分排序,源码如下,

private static void binarySort(Object[] a, int lo, int hi, int start) {
        assert lo <= start && start <= hi;
        if (start == lo)
            start++;
        for ( ; start < hi; start++) {
            Comparable pivot = (Comparable) a[start];

            // Set left (and right) to the index where a[start] (pivot) belongs
            int left = lo;
            int right = start;
            assert left <= right;
            /*
             * Invariants:
             *   pivot >= all in [lo, left).
             *   pivot <  all in [right, start).
             */
            while (left < right) {
                int mid = (left + right) >>> 1;
                if (pivot.compareTo(a[mid]) < 0)
                    right = mid;
                else
                    left = mid + 1;
            }
            assert left == right;

            /*
             * The invariants still hold: pivot >= all in [lo, left) and
             * pivot < all in [left, start), so pivot belongs at left.  Note
             * that if there are elements equal to pivot, left points to the
             * first slot after them -- that's why this sort is stable.
             * Slide elements over to make room for pivot.
             */
            int n = start - left;  // The number of elements to move
            // Switch is just an optimization for arraycopy in default case
            switch (n) {
                case 2:  a[left + 2] = a[left + 1];
                case 1:  a[left + 1] = a[left];
                         break;
                default: System.arraycopy(a, left, a, left + 1, n);
            }
            a[left] = pivot;
        }
    }
View Code
            while (left < right) {
                int mid = (left + right) >>> 1;
                if (pivot.compareTo(a[mid]) < 0)
                    right = mid;
                else
                    left = mid + 1;
            }

这个值是和已排序的数据的中间的数据进行比较,provot.compareTo(a[mid])

注意看,上面的a[mid]是作为比较方法的参数。

当小于0,也就是值为-1时,是我们要插入的数据作为调用方,

 

小于0时,该数据插入到前面,

大于0时,数据插入到后面

 

思维惯性以为升序就是第一个元素比第二个元素小。obj1.compareTo(Object obj2)

即obj1=2是第一个元素,obj2=8是第二个元素

那么我们升序时,如果obj1小于obj2,返回值为-1,则会将obj2插入到obj1前面,,排序前【2, 8】这样排序完后却变成了,,【8, 2】

这跟我们想要的升序数据不一样,

 

原因是java的二分法进行比较了是,,obj2.compareTo(obj1),,与我们想的刚好相反,

所以我们返回的值取反就可以变成升序了,

 

如这个消费类,,只给出部分代码

public class ConsumInfo implements Comparable<ConsumInfo> {
    public double price;
   public String name;
  public Consuminfo(double price, String name){
   this.price = price;
   this.name = name;
  } @Override
public int compareTo(ConsumInfo o) { //首先比较price,如果price相同 if(price < o.price){ return -1; } if(price > o.price){ return 1; } return 0; } }
    ConsumInfo consumInfo1 = new ConsumInfo("consumInfo1", 400.0);
       ConsumInfo consumInfo2 = new ConsumInfo("consumInfo2", 200.0);
    List
<ConsumInfo> list = new ArrayList<ConsumInfo>(); list.add(consumInfo1); list.add(consumInfo2);     System.out.println("排序前:");     for(ConsumInfo consumInfo : list ){ System.out.println(consumInfo); }     Collections.sort(list);//排序     System.out.println("排序后:");//排序后 for(ConsumInfo consumInfo :list){ System.out.println(consumInfo); }

控制台输出信息为:

排序前:
ConsumInfo [name=consumInfo1, price=400.0]
ConsumInfo [name=consumInfo2, price=200.0]
排序后:
ConsumInfo [name=consumInfo2, price=200.0]
ConsumInfo [name=consumInfo1, price=400.0]

上面是最简单的两个元素进行排序,

第一次,往已排序列表中插入第一个元素,即数组中只有一个已排好序的元素,a[0] = consumInfo1 

第二次时,left为0,right为1,进入while循环中,

mid=0,privot=consumInfo2

即consumInfo2.comparTo(a[0])

当方法的返回值小于0时,consumInfo2会插入在consumInfo1之前,

大于0时,会在consumInfo1之后

进行比较时,consumInfo2.price<consumInfo1.price    返回值小于0,也就是consumInfo1的值比较大,插入在1之前

posted @ 2018-08-21 17:09  海绵般汲取  阅读(4476)  评论(0编辑  收藏  举报