细说Java

来源:互联网 发布:小说改编的网络剧2015 编辑:程序博客网 时间:2024/06/12 20:22

一、异或

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

x=x^y;//将异或的中间结果存储在x中y=x^y;//利用上面的原理,将x异或y两次,得到以前的x值,赋值给yx=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 本类中
0 0
原创粉丝点击