整数

整数类型用于处理没有小数部分的数据,其中,有符号整数用于处理0、正整数和负整数。请注意,Java中没有无符号整数类型(只处理0和正整数)。

Java基本数据类型中的整数类型有:

  • byte,8位有符号整数。
  • short,16位有符号整数。
  • int,32位有符号整数。
  • long,64位有符号整数。

算术运算

代码中,算术运算包括:

  • 加法运算,使用+运算符,如10+3得13。
  • 减法运算,使用-运算符,如10-3得7。
  • 乘法运算,使用*运算符,如10*3得30。
  • 除法运算,使用/运算符,如10/3得3。整数除以整数会得到整数结果,如果需要得到浮点数结果,应确保被除数和除数中有一个为浮点数。
  • 求余数运算,也称为模(mod)运算,使用%运算符。如10%3得1。

需要注意的是,整数除以0会产生异常,在“代码流程控制”课时会讨论异常的处理。

下面的代码演示了整数的五种算术运算。

Java
import java.util.*;
public class Hello {
	public static void main(String[] args) {
		int x = 10;
		int y = 3;
		System.out.printf("x + y = %d \n",x+y);
		System.out.printf("x - y = %d \n",x-y);
		System.out.printf("x * y = %d \n",x*y);
		System.out.printf("x / y = %d \n",x/y);
		System.out.printf("x %% y = %d \n",x%y);
	}
}

代码输出结果如下图。

System.out.printf()方法用于格式化输出内容,其中,%符号用于定义格式化字符,需要显示%字符时需要%%进行转义,而%d表示输出结果为整数。

常用的转义字符包括如下表。

格式化字符说明
%b显示布尔数据,如true和false值。
%c显示字符。
%d显示十进制整数。
%e显示科学计数法。
%f显示浮点数,可指定显示的小数位,如%.2f格式会显示2位小数。。
%o显示八进制整数。
%s显示字符串,可用于任何类型的数据。
%x显示十六进制整数。
%%显示百分号。

下面的代码会以两位小数的形式显示浮点数。

Java
import java.util.*;
public class Hello {
	public static void main(String[] args) {
		float x = 10F;
		float y = 99.345F;
		System.out.printf("x=%.2f \n", x);
		System.out.printf("y=%.2f", y);
	}
}

代码执行结果如下图。

类型转换

Java中的整数类型有4种,它们的取值范围也有所不同;代码中,整数的运算可能会使用不同途径传递的数据,它们的类型也可能不同。

不同类型的数据进行计算时,应注意类型转换的一些基本原则:首先会将取值范围小的数据转换为取值范围大的类型,然后进行计算,计算结果的类型是取值范围大的类型。

下面的代码演示了int和long类型数据进行运算的结果。

Java
public class Hello {
	public static void main(String[] args) {
		int x = 10;
		long y = 99;
		System.out.printf("x + y = %d \n", x + y);
		System.out.println(((Object)(x+y)).getClass().toString());
	}
}

代码执行结果如下图。

代码中有两个输出结果,第一个显示了计算结果。第二个则有些复杂,首先使用了强制转换将x+y的结果转换为Object类型,然后,使用getClass()方法获取数据的原始类型,并通过toString()方法显示类型名称;最终显示x+y的结果的数据类型为Long,即64位有符号整数类型。

前例中的x和y的求和运算过程中,使用了隐式的类型转换,代码中,如果需要明确转换的目标类型,可以使用强制转换,如前例中的(Object)(x+y)就是将x+y的结果强制转换为Object类型。

强制类型转换时,在需要转换类型数据的前面使用一对圆括号定义目标类型;如下面的代码,会将y转换为int类型后进行计算。

Java
public class Hello {
	public static void main(String[] args) {
		int x = 10;
		long y = 99;
		System.out.printf("x + y = %d \n", x + y);
		System.out.println(((Object)(x+(int)y)).getClass().toString());
	}
}

代码执行结果如下图,我们可以看到,最终计算结果的类型是Integer,即32位整数类型。

增量运算与减量运算

增量运算包括前增量运算和后增量运算,都使用++运算符,执行的也都是加1操作。首先来看前增量运算,如下面的代码。

Java
public class Hello {
	public static void main(String[] args) {
		int x = 10;
		System.out.println(++x);
		System.out.println(x);
	}
}

代码执行结果如下图。

我们可以看到,“++x”表达式的值是x加1后的数据,也就是说,前增量运算时,会先进行加1操作,表达式和变量的结果都是加1后的数据。

后增量的不同点在于,“x++”表达式会先返回x的原始数据,然后进行x加1的操作,如下面的代码。

Java
public class Hello {
	public static void main(String[] args) {
		int x = 10;
		System.out.println(x++);
		System.out.println(x);
	}
}

代码执行结果如下图。

实际应用中,如果不需要使用增量表达式的值,只使用运算后的变量数据,则前增量和后增量的效果是一样的;但如果需要使用增量表达式的值,则需要很小心的区分前增量和后增量的区别。

减量运算执行减1操作,使用--运算符,同样分为前减量与后减量运算。其执行逻辑与增量运算相似,如下面的代码。

Java
public class Hello {
	public static void main(String[] args) {
		int x = 10;
		System.out.println(--x);
		System.out.println(x);
		int y = 10;
		System.out.println(y--);
		System.out.println(y);
	}
}

代码执行结果如下图。

位逻辑运算

整数与二进制的基本概念,请参考文章整数与二进制

Java中的位运算包括:

  • 位与运算,使用&运算符。两个数位都为1时结果为1,有一个数位为0时结果为0。
  • 位或运算,使用|运算符。两个数位有一个为1时结果为1,两个数据位都是0是结果为0。
  • 位取反运算,使用~运算符。二进制数位中1变0,0变1。
  • 位异或运算,使用^运算符。两个数位值不同时结果为1,相同时结果为0。

位移运算

Java中的位移运算包括:

  • 位左移,使用<<运算符,二进制位向左(高位)移动;无符号整数时,数位整体左移,数据的低位补0;有符号整数时,符号位不变,数据位左移,低位补0。如x<<3其实际执行的就是x*23的运算,即2<<3的结果为16。。
  • 位右移,使用>>运算符,二进制位向右(低位)移动;无符号整数右移运算时,数位整体右移,高位补0;有符号整数右移运算时,符号位不变,移动的数位用符号位数据填充。如x>>3执行的就是x/23的运算,即64>>3结果为8。
  • Java中还支持>>>运算符,同样用于位右移,但它不考虑符号位,数位整体右移,并使用0填充高位。

整数包装类

我们说过,Java是面向对象的编程语言,而原始类型在提供基本数据处理便利性的同时,也成了面向对象编程中的异类,不过,Java中也给出了面向对象的解决方案,即,这些基本的原始类型都有对应的类,如:

  • Byte类处理byte类型。
  • Short类处理short类型。
  • Integer类处理int类型。
  • Long类处理long类型。

这些类定义在java.lang包中,下面以int类型为例,需要将数据转换为Integer类时,可以使用valueOf()方法,其定义包括:

  • Integer.valueOf(int),参数指定原始数据。
  • Integer.valueOf(String),参数指定数据的字符串形式。
  • Integer.valueOf(String,int),参数一指定数据的字符串形式,参数二指定原始数据的进制,如2、8、10、16。

实际上,对基本类型数据的操作,大部分使用int类型都可以做到,但Integer类中定义了更多的扩展方法,如:

  • Integer.max(int x, int y)方法,比较x和y的大小,返回较大的数据。
  • Integer.min(int x, int y)方法,比较x和y的大小,返回较小的数据。
  • Integer.toBinaryString​(int i)方法,返回int数据的二进制形式字符串。
  • Integer.toHexString​(int i)方法,返回int数据的十六进制形式字符串。
  • Integer.toOctalString​(int i)方法,返回int数据的八进制形式字符串。
  • Integer.toString(int i)方法,将int数据转换为String类型。

下面的代码演示了toBinaryString​(int i)方法的应用。

Java
public class Hello {
	public static void main(String[] args) {
		byte x= 16;
		byte a = (byte) (x >> 2);
		byte b = (byte) (x << 2);
		System.out.println(Integer.toBinaryString(a));
		System.out.println(Integer.toBinaryString(b));
	}
}

代码执行结果如下图。

BigInteger类

BigInteger类定义在java.math包,用于处理任意大的整数。

构建BigInteger对象时,可以使用一系列的构造函数,如使用int、字符串等数据构建BigInteger对象时;此外,如果使用long类型的数据构建BigInteger对象,可以使用BigInteger.valueOf()方法。

BigInteger对象不能直接使用+、-、*、/、%等运算符,但可以使用相应的方法进行运算,如:

  • add​(BigInteger val),返回对象与参数相加的结果。
  • subtract​(BigInteger val),返回对象与参数相减的结果。
  • multiply​(BigInteger val),返回对象与参数相乘的结果。
  • divide​(BigInteger val),返回对象除以参数的结果。
  • remainder​(BigInteger val),返回对象除以参数的余数。
  • and​(BigInteger val),执行对象和参数的位与运算。
  • andNot​(BigInteger val),执行“对象& ~val”运算。.
  • or​(BigInteger val),执行对象和参数的位或运算。
  • not(),执行对象数的位取反运算。
  • xor​(BigInteger val),执行对象和参数的位异或运算。
  • shiftLeft​(int n),执行位左移运算,参数指定移动的位数。
  • shiftRight​(int n),执行位右移运算,参数指定移动的位数。
  • abs()返回对象的绝对值。
  • max​(BigInteger val),返回对象和参数中较大的那个对象。
  • min​(BigInteger val),返回对象和参数中较小的那个对象。
  • pow​(int exponent),执行求对象数据的exponent次方。
  • sqrt(),返回对象的算术平方根。
  • gcd​(BigInteger val),返回对象和参数的最大公约数。

下面的代码演示了BigInteger类的应用。

Java
import java.math.*;
public class Hello {
	public static void main(String[] args) {
		BigInteger x = BigInteger.valueOf(100);
		System.out.println(x.add(BigInteger.valueOf(99)));
		System.out.println(x.sqrt());
		System.out.println(x.gcd(BigInteger.valueOf(75)));
	}
}

代码执行结果如下图。

枚举类型

枚举类型属于自定义类型,用于组织一系列相关的数据值,如星期几、性别等具有特定范围的数据。

下面的代码,我们定义一个名为ESex的枚举类型,用于表示性别。

Java
public class Hello {
	enum ESex {unknow, male, female};
	public static void main(String[] args) {
				ESex sex = ESex.male;
		System.out.println(sex);
	}
}

本例中,ESex枚举类型包括三个枚举值,分别是unknow、male和female。main()方法中,我们定义了一个ESex类型的变量sex,指赋值为ESex.male值,执行代码结果如下图。

使用有名称的数据可以使数据的含义更直观,但在一些时候,可能需要相应的数值数据,如下面的代码,可以使用枚举变量的ordinal()方法获取枚举值对应的索引。

Java
public class Hello {
	enum ESex {unknow, male, female};
	public static void main(String[] args) {
				ESex sex = ESex.male;
		System.out.println(sex.ordinal());
	}
}

执行代码会显示1。枚举成员的索引值是从0开始的,而sex是第二个成员,所以,索引值为1。

需要将整数转换为特定的枚举值时,可以参考如下代码。

Java
public class Hello {
	enum ESex {unknow, male, female};
	public static void main(String[] args) {
				ESex sex = ESex.values()[1];
		System.out.println(sex);
	}
}

本例,使用枚举类型的values()方法返回所有枚举成员的数组,然后,同样使用从0开始的索引就可以获取相应的枚举值;执行代码如下图。

本站内容均为原创作品,转载请注明出处,本页面网址为:http://caohuayu.com/chy/article/Article.aspx?code=cc001003