部分JAVA基础知识概念区别分析
参考资料:菜鸟教程
1.修饰符
2.continue 和 break
**break 关键字**
菜鸟教程中:
break 主要用在循环语句或者 switch 语句中,用来跳出整个switch语句块。
break 跳出最里层的循环,并且继续执行该循环下面的语句。
代码示例:
for(int i=0;i<6;i++) {
System.out.println("i0:"+i);
while(++i==5) {
System.out.println("i1:"+i);
break;
}
System.out.println("i2:"+i);
}
结果如下:
continue关键字
菜鸟教程中:
continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。
在 for 循环中,continue 语句使程序立即跳转到更新语句。
在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。
和上述同样的代码中
for(int i=0;i<6;i++) {
System.out.println("i0:"+i);
while(++i==5) {
System.out.println("i1:"+i);
continue;
}
System.out.println("i2:"+i);
}
输出结果如下:
由此可加深理解break跳出while循环,执行下面的语句,而continue会跳转回到while中的判断语句,再进行下面的语句
在for循环中:
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ) {
if( x == 30 ) {
continue;
}
System.out.print( x );
System.out.print("\n");
}
结果如下
3.StringBuffer和StringBuilder
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
StringBuffer与String不同的方法:
代码 | 描述 |
---|---|
public StringBuffer append(String s) | 将指定的字符串s追加到此字符序列。 |
public StringBuffer reverse() | 将此字符序列用其反转形式取代。 |
public delete(int start, int end) | 移除此序列的子字符串中的字符。 |
public insert(int offset, int i) | 将 int 参数的字符串表示形式插入此序列中。 |
replace(int start, int end, String str) | 使用给定 String 中的字符替换此序列的子字符串中的字符。 |
StringBuffer sb1=new StringBuffer("sb1");
sb1.append("::");
System.out.println("after append:"+sb1);
sb1.reverse();
System.out.println("after reverse:"+sb1);
sb1.reverse();
sb1.delete(0,1);
System.out.println("after delete:"+sb1);
sb1.insert(0,"s");
System.out.println("after insert:"+sb1);
sb1.replace(0, 2, "this");
System.out.println("after replace:"+sb1);
结果如下
4.包装类、拆箱和装箱
八种基本数据类型并不支持面向对象编程,不具备“对象”的特性——不携带属性、没有方法可调用。
借助于非面向对象技术的做法有时也会带来不便,比如引用类型数据均继承了Object类的特性,要转换为String类型时只需要简单调用Object类中定义的toString()即可,而基本数据类型转换为String类型则要麻烦得多。为了解决此类问题,JAVA为每种基本数据类型分别设计了对应的类,称之为包装类。
基本数据类型 | 对应的包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
每个包装类的对象可以封装一个相应的基本类型的数据,并提供了其他一些有用的方法。包装类对象一经创建,其内容(所封装的的基本类型数据值)不可改变。
基本类型和对应的包装类可以相互装换:
- 由基本类型向对应的包装类转换称为装箱,例如把 int 包装成 Integer 类的对象;
- 包装类向对应的基本类型转换称为拆箱,例如把
Integer 类的对象重新简化为 int
自动装箱会执行valueOf函数,对于valueOf方法:
Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。 当值在指定范围内,会引用缓存中的同一个对象,当值超过指定范围时,会new一个新的对象。
Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象
Boolean:在内部提前创建好true和false两个对象,不会创建对象
Integer派别的范围:
Integer类的valueOf方法如下:
关于equals和==两种比较方法:
对于equals比较而言,equals比较的是内容本身,并且equal的参数是一个Object对象,我们传入的是一个int类型,所以会首先进行装箱,然后比较对象的value值。
- 当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。
- equals不会进行类型转换,必须满足类型和内容相同才为true。
例:
Integer a = 1;
Integer b = 2;
Long g = 3L;
Long h = 2L;
System.out.println(g.equals(a+b));//false
System.out.println(g.equals(a+h));//true
而对于==比较而言,当两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算),则比较的是数值(即会触发自动拆箱的过程)。
- 当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。
- 只需满足在指定范围内的内容相同即为true
总结:
- 需要知道什么时候会引发装箱和拆箱
- 装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。
- equals(Object o) 因为原equals方法中的参数类型是封装类型,所传入的参数类型(a)是原始数据类型,所以会自动对其装箱,反之,会对其进行拆箱
- 当两种不同类型用== 比较时,包装器类的需要拆箱, 当同种类型用 ==比较时,会自动拆箱或者装箱
包装类的应用
一、实现int 和Integer的相互转换
通过Integer类的构造方法将int装箱,通过 Integer类的 intValue方法将 Integer拆箱。例如:
Integer i=128;//自动装箱
int j=i;//自动拆箱
int m=500;
Integer obj=new Integer(m);//手动装箱
int n=obj.intValue();//手动拆箱
System.out.println("n="+n);
Integer obj1=new Integer(500);
System.out.println("obj等价于obj1?"+obj.equals(obj1));
要注意Integer 和int的区别:
①Integer是int的包装类,默认值为null,int是基本数据类型,默认值是0;(拆箱操作一定要注意封装类对象是否为null,若为null会抛出空指针异常)
②Integer表示的是对象的引用,当new一个Integer时,实际上时生成一个指针指向此对象;而int是基本数据类型,直接存储数值;
③Integer变量必须实例化后才能使用。
在int 和Integer比较时要注意:
-
int 和Integer在进行比较的时候,Integer会进行拆箱,转为int值与int进行比较。
-
Integer与Integer比较的时候,由于直接赋值的时候会进行自动的装箱,那么这里就需要注意两个问题,一个是-128<= x<=127的整数,将会直接缓存在IntegerCache中,那么当赋值在这个区间的时候,不会创建新的Integer对象,而是从缓存中获取已经创建好的Integer对象。二:当大于这个范围的时候,直接new Integer来创建Integer对象。
-
new Integer(1) 和Integer a = 1不同,前者会创建对象,存储在堆中,而后者因为在-128到127的范围内,不会创建新的对象,而是从IntegerCache中获取的。那么Integer a = 128, 大于该范围的话才会直接通过new Integer(128)创建对象,进行装箱。
原文链接:Java 的Integer、int与new Integer到底怎么回事?
Integer a0=10;//自动装箱变为Integer i=Integer.valueOf(10);Integer i会自动拆箱为i.intValue().
Integer b0=10;
System.out.println("a0=b0?"+(a0==b0));//true ①
Integer a1=128;
Integer b1=128;
System.out.println(a1.equals(b1));//true
System.out.println("a1=b1?"+(a1==b1));//false ②
int a2=10;
int b2=128;
System.out.println("a2=a0?"+(a2==a0));//true③
System.out.println("b2=b1?"+(b2==b1));//true ④
Integer a3=new Integer(10);
Integer b3=new Integer(10);
System.out.println("a3=b3?"+(a3==b3));//false ⑤
System.out.println("a3=a0?"+(a3==a0));//false
①分析源码可知当int i>=-128并且 i<=127时,第一次声明会将 i 的值放入缓存中,第二次直接取缓存里的数据,而不是重新创建一个Ingeter对象,那么第一个打印结果因为 i=10在缓存表示范围内,所以时true
②若超出[-128,127]范围,第一次创建对象的时候没有缓存,第二次创建了一个新的Integer对象,所以地址不同。
③Integer自动拆箱功能,也就是比较两个基本数据类型
④int和Integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比较
⑤用new关键字来创建两个对象,不存在缓存的概念。两个用new关键字创建的对象用==比较结果为false。
参考:彻底让你明白 Integer 类和 int 基本数据类型的区别
二、将字符串转换为整数
Integer类有一个静态的paseInt()方法,可以将字符串转换为整数。语法为:parseInt(String s,int radix);radix 为进制,可选,默认为十进制。
例:
String str[]= {"123","123abc","abc"};
for(String i:str) {
try {
int m=Integer.parseInt(i,10);
System.out.println(i+"可以转换为整数"+m);
}catch(Exception e) {
System.out.println(i+"无法转换为整数");
}
}
三、将整数转换为字符串
Integer 类有一个静态的 toString() 方法,可以将整数转换为字符串。例如:
int m=500;
String s=Integer.toString(m);
System.out.println("s="+s);//输出s=500
6.Arrays类
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
方法 | 作用 |
---|---|
public static int binarySearch(Object[] a, Object key) | 用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。 |
public static boolean equals(long[] a, long[] a2) | 如果两个long数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
public static void fill(int[] a,b,c,int val) | 用指定的 int 值替换b(包含)到c(不包含)的所有元素的值。若没有b,c,则是用指定的 int 值替换指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
public static void sort(Object[] a) | 对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。 |
举例如下:
public static void main(String[] args) {
String[] l1= {"cc","aa","bb","dd"};
String[] l2= {"ee","ff"};
String[] l3= {"aa","bb","cc","dd"};
Arrays.fill(l2,0,1,"gg");//将l2中的第一个元素换成“gg”
System.out.println("l2:"+Arrays.toString(l2));
boolean equ=Arrays.equals(l1, l3);//比较l1与l3的元素
System.out.println("l1与l2是否相等:"+equ);
Arrays.sort(l1);//将l1按升序排列
int pos=Arrays.binarySearch(l1, "aa");//查找此时“aa”所在位置
System.out.print("aa的位置在数组l1中的:"+pos);
}