一、异或

可以用异或来实现交换两个变量的值:
原理是:(x^y^y)==x;
如果一个变量异或另一个变量两次,将会得到异或以前的值;
因此可以使用该性质来实现对两个变量值的交换。

x=x^y;//将异或的中间结果存储在x中
y=x^y;//利用上面的原理,将x异或y两次,得到以前的x值,赋值给y
x=x^y;//异或x两次,得到以前y的值,赋值给x

二、循环语句的调整

1.嵌套循环的调整

//第一种循环:外层循环次数大于内层循环
int v1=100;
int v2=100;
int v3=10;
for(int i=0;i<v1;i++){
    for(int j=0;j<v2;j++){
        for(int k=0;k<v3;k++){
            dosomething();
        }
    }
}
//第二种循环:外层循环次数小于内层循环
int v1=100;
int v2=100;
int v3=10;
for(int i=0;i<v3;i++){
    for(int j=0;j<v2;j++){
        for(int k=0;k<v1;k++){
            dosomething();
        }
    }
}

由于CPU在内外之间的切换会有一定的开销,因此如果可能的话,应该尽可能较少内外层循环切换的次数。只需使最外层循环的次数最少,内层循环次数多即可。

2.重复使用的调整

//第一种:每次循环都要重新计算upperLimit(),造成浪费
for(int i=0;i<upperLimit();i++){
    dosomething();
}
//第二种:先在循环外将定值upperLimit()赋值给upper,不需每次循环都重新计算,但因为upper是在循环外,如果误用upper可能会造成错误
int upper=upperLimit();
for(int i=0;i<upper;i++){
    dosomething();
}
//第三种:在for循环初始条件中先计算好upperLimit()使得upper只能再循环中起作用
for(int i=0,upper=upperLimit();i<upper;i++){
    dosomething();
}

3.在循环中使用StringBuilder拼接对象

//使用“+”对String对象进行连接,如下所示。不过由于String对象时不可改变的,
//每次对String对象的拼接都会重新创建一个对象,以前的对象被丢弃,造成时间和空
//间的浪费
public String getString(String[] arr){
    String result="";
    for(int i=0;i<arr.length;i++){
        result+=arr[i];
    }
    return result;
}
//相对于String的不可变性,Java中提供了相应的可变类——StringBuilder,因为
//StringBuilder是可以改变的,在拼接的过程中直接改变原来对象,而不是创建新的
//对象,这样可以提高效率,程序修改如下(需要使用到StringBuilder中的成员方法
//append()和toString()):
public String getString(String[] arr){
    StringBuilder result=new StringBuilder("");
    for(int i=0;i<arr.length;i++){
        result.append(arr[i]);
    }
    return result.toString();
}

4.跳转控制——循环标签
Java中不能使用C/C++中的goto语句,但是可以使用循环标签来实现循环的跳转。当程序存在多重循环嵌套语句时,如果需要直接跳出最外层的循环(使用break),或是中止内层的循环,而从外层的循环继续进行(使用continue),都可以用循环标签实现
C/C++中goto语句可以随意跳转;但Java中循环标签只能跳出循环

  • 循环标签也可以放在与循环不相关的位置,只是这样做这个循环标签就没有什么意义了,而且循环体内就不能使用该标签(原因请看下一个要求);
  • 如果循环体中使用了某个标签,那么该标签与循环之间不能有任何语句(注释除外)。例如:
public void labelTest(){
    label1:
        dosomething();
    label2:
    //循环标签和循环体之间不能有任何语句(注释除外)
    while(true){
        for(int i=0;i<100;i++){
            for(int j=0;j<100;j++){
                if(i==10||j==10){
                    break label2;//直接跳出最外层的循环(即跳出while循环)
                }
            }
        }
    }
}

5.for/in循环
即for(item:collecion)循环依次对collection中的每个元素进行相关的操作,使得循环方便很多。例如:

public static void main(String[] args){
    for(String s:args){
            dosomething();
//相当于是将args数组中的元素依次赋给s,因此如果s是基本数据类型(即int,long,
//float等),在循环体中修改s的值并不会改变args,但是如果s是引用数据类型
//(即String等),则修改s也就会修改args.
    }
}

for/in循环的局限:
只能对集合或者数组的全部元素进行顺序操作,而在某些情况下,我们可能只需

  • 对其中部分元素进行操作,
  • 或者非顺序操作,

这时就不能用for/in循环。

三、数组

1.数组的声明

  • Java中声明数组的时候不能指定数组的大小,如下声明是错误的:
int[5] array;
int array[5];
  • 这两种声明也是有些细小区别的,如下:
int[] array1,array2;//int[]后面的array1和array2都是数组
int array3[],array4;//带[]的array3是数组,而后面的array4不是数组

2.数组的初始化
(1)一维数组的初始化有两种方式:

int[] a={1,2,3,4,5};//声明并直接初始化和赋值
 int[] a=new int[5];//声明并指定数组的大小,但并未赋值

第二种方式,如果要赋值的话,可以这样:

int[] a=new int[]{1,2,3,4,5};//如果直接赋值的话就不能指定数组的大小。
//即以下做法是错误的:
int[] a=new int[5]{1,2,3,4,5};//错误做法

(2)多维数组的初始化
在Java中多维数组可以是不规则的(每维的元素个数可以不同),在为多维数组分配空间时一定要从高维到低维分配:

int[][] a=new int[3][];
a[0]=new int[2];
a[1]=new int[3];
a[2]=new int[4];

对于矩阵数组(即每维元素个数相等),则可以采用比较简单的分配方式:

int[][][] a=new int[2][3][4];//一共有三维,2*3*4

(3)arraycopy的使用
arraycopy可以实现对数组的复制。
arraycopy的申明原型:

public static native void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);

arraycopy对基本数据类型和对象型数据类型的作用效果是不同的;

  • 如果数组元素类型为基本数据类型,那么数组复制后就类似于基本数据类型数据之间的赋值。
  • 如果数组元素类型为引用类型,那么数组复制之后就类似于引用类型变量的赋值,赋值后两个引用指向同一内存单元,其中一个引用对对象所做的任何改变将直接影响到另一个引用。

(四)参数传递

Java中的参数传递都是按值传递,没有像C++中的按引用传递(使用&)
1.基本数据类型的参数传递:

public static void pass(int ax,int bx){
//在调用方法时(如pass(a,b)),相当于进行了如下的隐含操作:
//ax=a;
//bx=b;
    ax=5;
    bx=29;
}

2.参数传递的是对象的引用
需留意修改的是引用本身,还是对象。
3.数组参数传递
4.String参数传递

(五)访问修饰符

访问修饰符

可见范围

public

所有

protect

本类中,本包中,包外子类

默认

本类中,本包中

private

本类中