您的位置:首页 > 职场人生

黑马程序员--Java基础之语法和数组总结

2013-03-10 22:02 519 查看
-------
android培训、java培训、期待与您交流! ----------
      标识符的命名:由26个英文字母的大小写、0-9数字、_和$字符组成,数字不可以作为开头,不能使用关键字,为了提高阅读性,尽量使用有意义的单词。java中的命名规范,包名:多单子组成时所有字母都小写xxyyyzzz,类名接口名:多单词组成时,所有的单词首字母大写XxxYyyZzz,变量名函数名:多单词组成时第一个单子小写,第二个单词开始首字母大写xxxYyyZzz,常量名:多有字母大写,单词之间用下划线_连接XXX_YYY_ZZZ。
      整数的进制形式:任何数据在计算机中都是以二进制形式存在的,即0或者1组成的数值。为了方便表示数据,人们将二进制缩短表示,从而有了十进制、八进制、十六进制三种形式。十进制是0-9,满10进1,八进制是0-7,满8进1,开头用0表示,十进制是0-9,A-F,满16进1,开头用0x表示。举例说明,十进制数60,二进制是111100,八进制是074,十六进制是0x3c。负数的二进制表现形式其实就是负数的取反再加1。
      转义字符:通过\来转变后面字母或者符号的含义
\n:表示换行
\b:退格,相当于Backspace
\r:按下回车键,windows系统下回车符是俩个字符\r\n
\t:制表符,相当于tab键
     类型的转换问题:运算中会遇到类型的转换问题,这涉及到类型的自动转换。
int a=1;
a=a+3;
a+=3;
//以上运行没有问题
short s=1;
s=s+3;//运行会出错,报类型错误
s+=3;//运行没有问题
/*
s=s+1做了俩次操作,一次是加法运算,一次是赋值运算,加法运算时s是short类型,加上一个整型3后,低类型的short自动转换成整型,所以结
果是将整型赋值给short类型的s,那么此时必然会出现类型错误。同样的道理,a本来是整型,它的运算是没有错误的。
s+=3只做了一次赋值运算,它就像short s=1时的赋值,会产生一个自动装换类型的动作,将整型1转换成了short类型,这样的运行结果没有问题。
*/
s=(short)(s+3);//这样做过强制类型转换后才是正确的
      &和&&,|和||的特点:&无论左边是true或者false,右边都运算,&&当左边为false时,右边不运算。|两边都参与运算,||当左边为true时,右边不参加运算。
      位运算的使用方法:计算机运算时,最快的运算方法是位运算,其中包括左移(<<)、右移(>>)、与(&)、或(|)、异或(^)、反码(~)。
      3<<2;//结果为12,即3*2的2次幂,乘以2的移动的位数次幂

      12>>2;//结果为3,即12/2的2次幂,除以2的移动的位数次幂

      3<<2示例:

      3的二进制:        0000-0000 0000-0000 0000-0000 0000-0011

      左移2位后:        0000-0000 0000-0000 0000-0000 0000-1100(末尾用0补)

      12>>2示例:

      12的二进制:      0000-0000 0000-0000 0000-0000 0000-1100

      右移 2 位 后:     0000-0000 0000-0000 0000-0000 0000-0011(前面用最高位0补)

      >> 最高位补什么由原有数据的最高位值而定

      如果最高位0,右移后,用0补空位

      如果最高位1,右移后,用1补空位

      >>>无论最高位是什么,右移后都用0补

      &,|,^,~即将数字转换成二进制形式,再对其进行相应的运算。注意:一个数异或一个数俩次还是它本身。

      示例:6&3=2;       6|5=7;      6^5=3;      ~6=-7;

                  110            110          110          ~ 0000...0110

                &011           |101         ^101            1111...1001//最高位是1则为负数,正数取反再加1即为负数,相反操作后(减1再取反)得到为7,即值为7的负数

                 -------          -------        -------

                   010 =2      111 =7     011 =3
      效率最高的运算方法:正常运算时我们计算2乘以8即2*8,但是计算机最终运算还是转换成位运算,所以运算时直接写成位运算是效率最高的方法,即写成2>>3。
      俩个整数值进行互换的三种方法:分别是需要第三方变量和不需要第三方变量,其中不需要第三方变量时包含俩种方法。
int m = 5, n = 8;
// 需要第三方变量的方法,该方法简单易懂,实际开发中基本都使用该方法
int tmp = m;
m = n;
n = tmp;
System.out.println("m=" + m + ",n=" + n);
//使用累计俩数之和再分别求差值
m=m+n;
n=m-n;
m=m-n;
System.out.println("m=" + m + ",n=" + n);
//使用 一个数异或另一个数俩次还是该数本身的原理
m=m^n;
n=m^n;
m=m^n;
System.out.println("m=" + m + ",n=" + n);

     switch语句结束的注意点:在使用switch语句时,每当匹配到相应的值则执行相应的case语句块,若不存在匹配的语句块则执行default,当default执行完毕后,按照从上往下的顺序继续执行到switch语句块的末尾}处。若满足一个条件,default在上方或者中间时,而又匹配到default去执行它的语句,那么当default执行完毕后,程序switch语句不是执行结束,而是接着往下执行。
int a = 7;
switch (a) {
default:
System.out.println(a);//a是7,当程序判断完既不是1也不是2后执行到此处的default
case 1:
System.out.println(a);//程序执行完default后不是结束程序,而是再继续向下执行
break;
case 2:
System.out.println(a);
break;
}//最终结果输出了2个7

     while和do-while的区别:while(循环条件) {循环体}是先判断循环条件,再执行循环体,do{循环体}while(循环条件)是先执行循环体,再执行循环条件,当满足循环条件处于临界值时,俩者可能会出现结果的不同。
int sum=5;
while(sum<5){
sum++;
}
System.out.println(sum);//循环结束后输出结果是5,先判断5是否小于5,不满足条件不执行循环,sum仍然是5
sum=5;
do{
sum++;
}while(sum<5);
System.out.println(sum);//循环结束后输出结果是6,先执行循环sum加1后是6,然后判断sum是否小于5,不满足条件不执行下次循环,sum是6

     栈和堆的一些特点:栈存放的是局部变量内容,例如方法中定义的变量,方法参数定义的变量,for()循环中定义的变量,另外main方法,调用的show方法都是在栈中开辟的,在栈中开辟的内存空间一使用完则立即释放。int[] x=new int[3],其中x是临时变量存放在栈中,而所有new出来的实体都是存在堆中,该数组在堆中开辟了一个存放数组值的空间,该空间的首地址值(起始位置)保存在变量x中,即首地址指向了x,访问数组x时则通过其首地址来访问。堆有三个特点,第一是堆内存的实体都有空间地址值,所有在堆中开辟空间的实体都有一个地址值,通过该地址访问存放在堆中的数据;第二是堆内存的实体的都有默认初始化值,例如int数组的初始化值都为0,f
4000
loat数组初始化值都为0.0f,double数组初始化值都为0.0,boolean数组初始化值都为false,string数组初始化值都为""空;第三是堆内存垃圾回收机制,当堆空间中的实体不再被使用时(没有任何引用使用它,例如x=null后,x原有的引用空间变成废空间,或者x被重新赋值新的引用),jvm虚拟机会不定时清理释放内存。java成长于c++,内存空间的优化比c++好,c++是程序员手动释放垃圾内存,若忘记释放则可能导致程序越用越卡,甚至导致死机,而java是jvm虚拟机不定时调用垃圾回收机制来释放内存。
      选择和冒泡排序方法:排序有许多种方法,比较容易理解和常用的方法是一下的选择和冒泡排序,另外还有快速排序、哈希排序等,效率最高的是哈希排序。Java中封装了一种优化好的排序方法,即Arrays.sort(arr)这种方法,它是开发中比较常用的方法。排序的本质都需要进行元素位置的互换,下面排序中的互换都是在堆内存中进行频繁的互换,相对而言比较耗内存,可以使用临时变量存储下标,最后比较完毕时再将相应的元素进行互换,这样减少了数组元素互换的次数,使用临时变量代替,原理是减少了堆内存的交换次数而用栈内存的交换代替,优化了性能。
      1、选择排序原理:从第一个元素开始和后面每一个元素比较,将最小元素放到第一个元素处,然后从第二个元素开始向后比较,将第二小的元素放在第二个位置,依次进行长度-1次的比较。
for(int i=0;i<a.length-1;i++)
{//外层循环条件是长度-1次,因为最后一次不需要比较,只剩下一个最大值在末尾
for(int j=i+1;j<a.length;j++)
{//内层循环每次都是拿当前i元素的后一个开始比较,按次向后直到最后一个,将每一个元素和起始的元素比较
if(a[i]>a[j])
{//每当起始元素比和它比较的元素大时,将它们互换,保证每层内循环结束都是最小元素在i的起始位置
int tmp=a[i];
a[i]=a[j];
a[j]=tmp;
}
}
}
       2、冒泡排序原理:将相邻的俩个元素进行比较,一直比较到最后一个元素,最大的元素将被换到最后一个位置,然后继续从第一个元素开始俩俩相邻比较,一直比较到倒数第二个,下一轮则比较到倒数第三个,每轮比较将小的元素往前浮,类似冒泡。
for (int i = 0; i < a.length-1; i++) {//外层循环执行长度-1次,俩俩相邻比较,最后一次是一个最值不需要
for (int j = 0; j < a.length - i - 1; j++) {//由于每轮比较的最值在最后,每轮比较次数都减少,-i让每次比较的元素减少
if (a[j] > a[j + 1]) {//-1是为了让元素角标不越界,若j能取到length-1,则a[j+1]即a[length]是取不到的
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
 
    3、排序的位置置换功能抽取:排序的核心是元素的位置置换,不管什么排序都需要,我们可以将其功能抽取封装成一个方法。
//参数列表的数组是用来获取数组地址从而使元素交换,整型a和b是用来存储交换的俩个元素下标
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr;
arr[b] = temp;
}
     [b]数组的折半查找:折半查找一般只用于一组已经排好序的数组,当要确定一个元素在该有序数组中的位置时,使用折半查找效率比较高,它的原理是从数组中间位置开始比较,若大于中间元素则以中间元素后的元素到最后一个元素为范围,然后继续取中间元素比较,若小于中间元素则以第一个元素到中间元素为范围,然后取中间元素比较。同时一道面试题也有它的应用,求如何将一个数插入到一组有序数组中?这里也是先用折半查找法找出该元素在该有序数组中的适当位置,再将其插入并将其它元素移动。折半查找法结束都是以min值都是比max值大的条件而结束循环,举例说,若以数组5,8,10中查找7来计算,最后三次值得情况是:min是5的位置0,max是8的位置1;min是8的位置1,max是8的位置1;min是8的位置1,max是7的位置0。
// 折半查找的第一种方法
public static int halfSearch1(int[] arr, int key) {
int min = 0;
int max = arr.length - 1;
int mid = (min + max) / 2;
while (key != arr[mid]) {//当值不等于中间元素时一直循环
if (key > arr[mid])
min = mid + 1;//当值大于中间元素时,最小范围变成中间位置向右进一位
else if (key < arr[mid])
max = mid - 1;//当值小于中间元素时,最大范围变成中间位置向左减一位
if(min>max)//当最小范围大于最大范围时代表已经全部比较过不存在查询的值
return -1;
mid=(min+max)/2;
}
return mid;
}

// 折半查找的第二种方法
public static int halfSearch2(int[] arr, int key) {
int min = 0;
int max = arr.length - 1;
int mid = (min + max) / 2;
while (min <= max) {//当最小范围小于最大范围时进行查找的循环
if (key > arr[mid])
min = mid + 1;
else if (key < arr[mid])
max = mid - 1;
else
return mid;
mid=(min+max)/2;
}
return -1;//return min;若是面试题,当查找不到值时返回min最小范围就是插入的位置,恰好是比它小的元素的后一个位置
//比如说数组4,6,9中插入7,那么最后7是大于6小于9的,最后返回的结果是2,恰好是9这个位置。
}
 
    十进制转换二进制和十六进制:十进制数转换成二进制,将数先取模2,得到的数是1或0,它是二进制数的最后一位,然后将该数除2运算,得到的数继续刚才的运算,直到数本身是1为止。十进制数转换成十六进制数,每次应该取它二进制的最后四位,将其转换成十六进制数的表现形式,同时每次最后四位运算完后将其本身向右移4位,这里将它与15取模,得到的就是它的最后四位二进制数,根据大于9则是字母,小于等于9则是本身的原理进行转换,然后将其向右移4位后继续运算。
// 十进制转换二进制
public static void toBin(int num) {
StringBuffer sb = new StringBuffer();
while (num > 0) {
sb.append(num % 2);// 将数取模2得到十进制的最后一位
num = num >>> 1;// 位移1位后继续运算
}
System.out.println(sb.reverse());// 由于字符串是十进制的倒序,需要将字符串反向
}

// 十进制转换十六进制
public static void toHex(int num) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 8; i++)// 整型是4个字节,每个字节8位,所以每个整型至多位移操作8次
{
int tmp = num & 15;// 每次对15进行&与运算时都会得到最后4位的二进制数
if (tmp > 9) {// 当该数大于9时则要转换成十六进制的字母,因为十六进制是由0-9,A到F组成的
sb.append((char) (tmp - 10 + 'A'));
} else {
sb.append(tmp);
}
num = num >>> 4;// 将数向右移4位,继续运算它最后的4位二进制数
}
System.out.println(sb.reverse());
}
 
    查表法和进制转换优化:查表法就是将需要表达的字符放在数组里,使用它的变量作为该数组的下标值,例如char[] chs=new{'0','1','A'},此时引用变量就是用0和1,chs[0]即是字符0,chs[2]即是字符A。将几个转换方法写完后发现有很多代码都是公用的,将其抽取出来封装成一个方法,再对代码优化,具体方法如下:
public static void main(String[] args) {
System.out.println(toBin(6));
System.out.println(toHex(60));
System.out.println(toOct(60));
}
/*
* 十进制转换二进制
*/
public static String toBin(int num) {
return trans(num, 1, 1);
}
/*
* 十进制转换八进制
*/
public static String toOct(int num) {
return trans(num, 7, 3);
}
/*
* 十进制转换十六进制
*/
public static String toHex(int num) {
return trans(num, 15, 4);
}
/*
* 进制转换公用方法
*/
public static String trans(int num, int base, int offset) {
StringBuffer sb = new StringBuffer();
if (num == 0) {//当传递的数是0时直接结束函数,返回0
sb.append("0");
return sb.toString();
}
//用于查找的字符表
char[] chs = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'B', 'C', 'D', 'E', 'F' };
char[] arr = new char[32];//一个十进制整型是4个字节,一共32位有效位
int pos = arr.length;//定义存储到字符数组的指针从最后一位开始,即倒序存储转换后的结果
while (num != 0) {//当位移后的数字为0时结束循环
int temp = num & base;//存储转换后的数值
arr[--pos] = chs[temp];//将查表后的结果倒序存储到数组arr中,pos为每次存储的指针
num = num >>> offset;//将转换后的数字位移相应的位数
}
for (int i = pos; i < arr.length; i++) {
sb.append(arr[i]);//从最后存储的位置开始,读取到最后一位
}
return sb.toString();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java