java编程基础第四天

---------------------- android培训java培训、期待与您交流! ----------------------


  数组的格式:回顾第一种格式:

int[] arr=new int[3];//arr是array的缩写。

也可以这样写:int arr[]=new int[3];推荐上面的规范写法。

第二种格式:元素类型[]  数组名=new 元素类型[]{ 元素,元素,……};比如:int[] arr=new int[]{3,1,6,5,4};也可以简化写成:int[] arr={3,1,6,5,4,};


  数组的常见问题:

1.数组角标越界异常:
int[] arr=new int[3];

System.out.println(arr[3]);

编译的时候不会报错,因为只是检查语法错误,在运行的时候就会提示ArrayIndexOutOfBoundsException,意思是数组角标越界异常,数组在操作中访问到了不存在的角标。原因是在arr这个数组中有三个元素,角标分别是0,1,2,而没有3号角标,所以运行会报错。


2.空指针异常:
int[] arr=new int[3];
arr=null;
System.out.println(arr[1]);

同样是在运行的时候报错,提示NullPointerException,意思是空指针异常,因为引用没有任何指向,但引用还在操作实体。


  数组的操作:

获取数组中的元素是数组最常见的操作。一般是用遍历的方式。

class Test
{
    public static void main(String[] args)
    {
    int[] arr=new int[3];
    for(int x=0;x<3;x++)
    {
        System.out.println("arr["+x+"]="+arr[x]);      
    }

    }    
}

假如数组中的元素非常多,无法确定元素个数,此时需要用到length,这个参数可以直接获取数组中元素的个数,使用格式:数组名称.length,比如:

class Test
{
    public static void main(String[] args)
    {
        int[] arr={1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1};
        System.out.println("length="+arr.length);
        for(int x=0;x<arr.length;x++)
        {
            System.out.println("arr["+x+"]="+arr[x]);
        }
    }    
}

同样可以求和:

class Test
{
    public static void main(String[] args)
    {
        int[] arr=new int[]{1,2,3,4,5,6,7,8,9,};
        int sum=0;
        for(int x=0;x<arr.length;x++)
        {
            sum+=arr[x];    
        }
        System.out.println(sum);
    }    
}

应用举例:

1.打印数组中的元素,元素间用逗号隔开。

class Test
{
    public static void main(String[] args)
    {
        int[] arr={1,2,3,4,5};
        printArr(arr);
        printArr(arr);
    }
    public static void printArr(int[] arr)
    {
        System.out.print("[");
        for(int x=0;x<arr.length;x++)
        {
            if(x!=arr.length-1)
            {
                System.out.print(arr[x]+", ");
            }            
            else
            {
                System.out.println(arr[x]+"]");
            }
        }
    }   
}

注意:如果输入System.out.println(arr);结果会显示,[I@6bade9,其中中括号表示是数组,大写i表示int,@后面的就是这个数组在堆内存中的十六进制地址,是一个用哈希算法算出的哈希值。


2.求最值:

/*
需求:获取数组中的最大值。

思路:
1.获取最值需要进行比较,每次比较都会有一个较大值,因为值不确定,需要通过一个变量进行临时存储。
2.让数组中每一个元素都和这个变量中的值进行比较。如果大于变量中的值,就替换掉变量中的值。
3.当所有元素都比较完成,那么变量中的值就是最大值了。

步骤:
1.定义变量,初始化为数组中的任意一个元素即可。
2.通过循环语句对数组进行遍历。
3.在遍历中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给变量。

需要定义一个功能来完成。
1.结果明确,数组中的最大元素,int。
2.有未知内容,一个数组,int[]。
*/

class Test

{
    public static int getMax(int[] arr)
    {
        int max=arr[5];
        for(int x=0;x<arr.length;x++)
        {
            if(arr[x]>max)
            {
                max=arr[x];
            }
        }
        return max;
    }
    public static void main(String[] args)
    {
        int[] arr={2,5,8,4,7,10};
        int a=getMax(arr);
        System.out.println(a);
    }
}

最小值同理。求最值另一个方法:就是初始化为角标,而不是数组中的任意一个数。
class Test
{
    public static int getMax(int[] arr)
    {
        int max=0;
        for(int x=1;x<arr.length;x++)
        {
            if(arr[x]>arr[max])
            {
                max=x;
            }
        }
        return arr[max];
    }
    public static void main(String[] args)
    {
        int[] arr={2,5,8,4,7,10};
        int a=getMax(arr);
        System.out.println(a);
    }

}

如果是获取double类型的最值,由于函数的功能都是求最值,所以以重载的方式定义函数:

public static double getMax(double[] arr);


2.对给定数组排序:

1.选择排序:把数组中的第一个数和其他数依次比较,可以确定出整个数组的最值,然后在把第二位的数和剩下的数依次比较,就可以确定余下数组的最值,然后一直比到最后.

class Test
{
    public static void selectSort(int[] arr)//没有返回值,所以是不确定。
    {
        for(int x=0;x<arr.length-1;x++)//最后一次比较没有必要,所以是x<arr.length-1。
        {
            for(int y=x+1;y<arr.length;y++)//注意写法,y每次都是比x大1,所以不要定义成常量,定义成随x变化的变量。内循环结束一次,最值出现在头角标位.
            {
                if(arr[x]>arr[y])//如果是降序排序,只需改成>即可.
                {
                    arr[x]=arr[x]^arr[y];
                    arr[y]=arr[x]^arr[y];
                    arr[x]=arr[x]^arr[y];
                }
            }
        }
    }
    public static void printArray(int[] arr)
    {
        System.out.print("[");
        for(int x=0;x<arr.length;x++)
        {
            if(x!=arr.length-1)
            {
                System.out.print(arr[x]+", ");
            }
            else
            {
                System.out.println(arr[x]+"]");
            }
        }
    }
    public static void main(String[] args)
    {
        int[] arr={4,7,8,3,9,2};
        printArray(arr);//排序前
        selectSort(arr);//排序
        printArray(arr);//排序后        
    }
}

2.冒泡排序:BubbleSort,依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。

class Test
{
    public static void bubbleSort(int[] arr)
    {
        for(int x=0;x<arr.length-1;x++)//因为是相邻比较,最后一位要减掉.
        {                        
            for(int y=0;y<arr.length-x-1;y++)//-x为了每次比较的元素少一个,-1是为了防止越界.
            {
                if(arr[y]>arr[y+1])//改变成<即是从大到小.
                {
                    arr[y]=arr[y]^arr[y+1];
                    arr[y+1]=arr[y]^arr[y+1];
                    arr[y]=arr[y]^arr[y+1];
                }
            }
        }
    }
    public static void printArray(int[] arr)
    {
        System.out.print("[");
        for(int x=0;x<arr.length;x++)
        {
            if(x!=arr.length-1)
            {
                System.out.print(arr[x]+", ");
            }
            else
            {
                System.out.println(arr[x]+"]");
            }
        }
    }
    public static void main(String[] args)
    {
        int[] arr={3,7,5,2,8};
        printArray(arr);
        bubbleSort(arr);
        printArray(arr);        
    }
}

目前最有效率最快的排序是希尔排序.

如果数组中的数据非常多,用selectsort和bubblesort就比较费时了,因为每次都要换位置,在堆内存中换位置比较耗资源.

在java中java提供了能自动排序的工具,在代码的第一行输入import java.util.Arrays;然后就可以在主函数调用了:

import java.util.Arrays;
class Test
{

public static void printArray(int[] arr)
    {
        System.out.print("[");
        for(int x=0;x<arr.length;x++)
        {
            if(x!=arr.length-1)
            {
                System.out.print(arr[x]+", ");
            }
            else
            {
                System.out.println(arr[x]+"]");
            }
        }
    }

public static void main(String[] args)
    {
        int[] arr={7,4,9,2,5,3};
        printArray(arr);
        Arrays.sort(arr);//当在第一行输入了import java.util.Arrays;之后就可以在这里直接输入Arrays.sort(arr);来调用了,但默认是升序.
        printArray(arr);           
    }

}

所以如果想要降序,排列,则在输入Arrays.sort(arr)之后,再打印的时候从最后一位开始后打印不就是降序了,比如:

import java.util.Arrays;
class Test
{
    public static void printArray(int[] arr)
    {
        System.out.print("[");
        for(int x=arr.length-1;x>=0;x--)//注意这里是从数组的最后一位开始遍历到第一位.
        {
            if(x!=0)
            {
                System.out.print(arr[x]+", ");
            }
            else
            {
                System.out.println(arr[x]+"]");
            }
        }
    }
    public static void main(String[] args)
    {
        int[] arr={3,7,6,2,9,5};
        Arrays.sort(arr);
        printArray(arr);
    }
}

发现在selectsort和bubblesort都需要进行位置的置换,所以可以把这部分代码单独封装成函数.

class Test
{
    public static void main(String[] args)//主函数.
    {
        int[] arr={7,4,6,9,2,4,1};
        printArray(arr);
        System.out.println(setMin(arr));
        //selectSort(arr);
        bubbleSort(arr);
        printArray(arr);
    }
    public static void swap(int[] arr,int x,int y)//置换数组中的两个元素.
    {
        arr[x]=arr[x]^arr[y];
        arr[y]=arr[x]^arr[y];
        arr[x]=arr[x]^arr[y];
    }
    public static int setMin(int[] arr)//求数组中的最小值.
    {
        int min=0;
        for(int x=1;x<arr.length;x++)
        {
            if(arr[min]>arr[x])
            {
                swap(arr,min,x);
            }
        }
        return arr[min];
    }
    //控制打印的顺序也可以控制数组的升降序.
    public static void printArray(int[] arr)//从第一个角标开始依次打印出数组中的元素.
    {
        System.out.print("[");
        for(int x=0;x<arr.length;x++)
        {
            if(x!=arr.length-1)
            {
                System.out.print(arr[x]+", ");
            }
            else
            {
                System.out.println(arr[x]+"]");
            }
        }
    }
    public static void selectSort(int[] arr)//选择排序.升序.
    {
        for(int x=0;x<arr.length-1;x++)
        {
            for(int y=x+1;y<arr.length;y++)
            {
                if(arr[x]>arr[y])//控制升序还是降序.
                {
                    swap(arr,x,y);
                }
            }
        }
    }
    public static void bubbleSort(int[] arr)//冒泡排序,升序.
    {
        for(int x=0;x<arr.length-1;x++)
        {
            for(int y=0;y<arr.length-x-1;y++)
            {
                if(arr[y]>arr[y+1])//控制升降序.
                {
                    swap(arr,y,y+1);
                }
            }
        }
    }
}


  查找数组中某个元素的角标.

/*

定义功能:查找key第一次出现在数组中的位置,假如有两个相同的key,只会返回第一个key的位置.

*/

class Test
{
    public static void main(String[] args)
    {
        int[] arr={3,6,2,7,5,1,9};
        System.out.println(getIndex(arr,10));
    }
    public static int getIndex(int[] arr,int key)
    {
        for(int x=0;x<arr.length;x++)
        {
            if(arr[x]==key)
            {
                return x;
            }
        }
        return -1;//惯例是当数组中所求元素角标不存在的时候,默认返回-1.
    }
}


  上面的查找方式是挨个查找,可以用于有序或者无序的数组,但如果元素多就比较费时.对于有序数组可以用折半查找方式,要么数组从小到大,要么从大到小.

  折半查找,例一:

class Test
{
    public static void main(String[] args)
    {
        int[] arr={3,5,9,35,67,89,150};
        System.out.println(halfSearch(arr,150));
    }
    public static int halfSearch(int[] arr,int key)
    {
        int min,max,mid;
        min=0;
        max=arr.length-1;
        mid=(min+max)/2;
        while(arr[mid]!=key)
        {
            if(arr[mid]<key)
            {
                min=mid+1;
            }
            else if(arr[mid]>key)
            {
                max=mid-1;
            }
            if(min>max)
            {
                return -1;
            }
            mid=(min+max)/2;
        }
        return mid;
    }
}

  折半查找,例二:

public static int halfSearch_2(int[] arr,int key)
    {
        int min=0,max=arr.length-1,mid;
        while(min<=max)
        {
            mid=(min+max)>>1;
            if(key>arr[mid])
            {
                min=mid+1;
            }
            else if(key<arr[mid])
            {
                max=mid-1;
            }
            else
            {
                return mid;
            }
        }
        return -1;
    }

  折半查找扩展,需求:有一个有序的数组,要将一个元素插入到该数组中,并保证该数组还是有序的.先对在数组中查找要插入的那个数是否存在,如果存在,就把这个数放在数组中已有的那个位置上,然后顺延,如果不存在,则不要返回-1,返回min,min就是那个数要插入的角标位置.比如

public static int halfSearch_2(int[] arr,int key)
    {
        int min=0,max=arr.length-1,mid;
        while(min<=max)
        {
            mid=(min+max)>>1;
            if(key<arr[mid])
            {
                max=mid-1;
            }
            else if(key>arr[mid])
            {
                min=mid+1;
            }
            else
            {
                return mid;
            }
        }
        return min;
    }
    public static void main(String[] args)
    {
        int[] arr={3,5,8,9,34,67,99};
        System.out.println(halfSearch_2(arr,37));
    }

 结果会显示5,那么5就是37所要插入的角标位置.


  练习:

1.十进制转二进制:

public static void toBin(int num)
    {
        while(num>0)
        {
            System.out.println(num%2);
            num=num/2;
        }
    }
    public static void main(String[] args)
    {
        toBin(6);
    }

如果要按顺序显示则可以用一个容器进行存储,再反向打印.

public static void toBin(int num)
    {
        StringBuffer sb= new StringBuffer();//用于存储数据的容器.
        while(num>0)
        {
            sb.append(num%2);//添加新的数据到这个容器.
            num=num/2;
        }
        System.out.println(sb.reverse());//反向打印.
    }
    public static void main(String[] args)
    {
        toBin(6);        
    }


2.十进制转十六进制:

public static void main(String[] args)
    {
        tohex(60);
    }
    public static void toHex(int num)
    {
        StringBuffer sb=new StringBuffer();
        for(int x=0;x<8;x++)//因为一个int含四个八位,也就是八个四位,一个四位代表一个十六进制数,所以最多只能右移八次.
        {
            int temp=num&15;
            if(temp>9)
            {
                sb.append((char)(temp-10+'A'));
            }
            else
                sb.append(temp);
            num=num>>>4;
        }
        System.out.println(sb.reverse());
    }

十进制转十六进制的另一种方法:

/*

  十六进制的十六个数刚好对应数组的角标,如果建立一个表,表示十六进制的数和数组角标的对应关系,那么在&15之后的数就不用再减10加'A'了,直接查表就可以知道对应的字母.

0     1    2    3    4    5    6    7    8    9     A      B      C      D      E      F

0     1    2    3    4    5    6    7    8    9    10    11    12    13    14    15

*/

public static void main(String[] args)
    {
        toHex(60);
    }
    public static void toHex(int num)
    {
        char[] chs={'0','1','2','3',
                    '4','5','6','7',            
                    '8','9','A','B',
                    'C','D','E','F',};
        for(int x=0;x<8;x++)
        {
            int temp=num&15;
            System.out.print(chs[temp]);
            num=num>>>4;
        }
    }

但是打印的结果是倒着的,需要用一个像StringBuffer一样的来存储数据,进行反向打印,这里用数组来代替StringBuffer进行存储.

public static void main(String[] args)
    {
        toHex(60);
    }
    public static void toHex(int num)
    {
        char[] chs={'0','1','2','3',
                    '4','5','6','7',
                    '8','9','A','B',
                    'C','D','E','F'};//定义一个十六进制表.
        char[] arr=new char[8];//定义一个临时容器.int类型的十六进制最多是一个八位,二进制是四个八位.所以这里的容器长度是8.
        int pos=arr.length;//定义一个指针.
        while(num!=0)
        {
            int temp=num&15;
            arr[--pos]=chs[temp];
            num=num>>>4;
        }
        for(int x=pos;x<arr.length;x++)
        {
            System.out.print(arr[x]);//如果挨个对arr进行打印,就会打印出空格,这个空格是'\u0000','是字符数组被定义后的初始化值,表示一个空位,相当于一个空格u表示Unicode,
        }
    }

上面这个代码是通用的,同样可以用于十进制转二进制.

public static void main(String[] args)
    {
        toBin(60);
    }
    public static void toBin(int num)
    {
        char[] chs={'0','1'};//定义一个二进制表.
        char[] arr=new char[32];//定义一个临时存储容器.
        int pos=arr.length;//定义一个操作数组的指针.
        while(num!=0)
        {
            int temp=num&1;
            arr[--pos]=chs[temp];
            num=num>>>1;
        }
        for(int x=pos;x<arr.length;x++)
        {
            System.out.print(arr[x]);
        }
    }


  发现在进行十进制转二进制和八进制,十六进制的时候,有共用的代码,所以提取出共用代码之后:

public static void main(String[] args)
    {
        toBin(60);
        toOct(60);
        toHex(60);
    }
    public static void trans(int num,int base,int offset)//进制转换的共用部分.三种转换不同是模以的基数和移位的数.
    {
        if(num==0)
        {
            System.out.println(0);
            return;
        }
        char[] chs={'0','1','2','3',
                    '4','5','6','7',
                    '8','9','A','B',
                    'C','D','E','F',};
        char[] arr=new char[32];
        int pos=arr.length;
        while(num!=0)
        {
            int temp=num&base;
            arr[--pos]=chs[temp];
            num=num>>>offset;
        }
        for(int x=pos;x<arr.length;x++)
        {
            System.out.print(arr[x]);
        }
        System.out.println();
    }
    public static void toBin(int num)//十进制转二进制.
    {
        trans(num,1,1);
    }
    public static void toOct(int num)//十进制转八进制.octonary八进制.
    {
        trans(num,7,3);
    }
    public static void toHex(int num)//十进制转十六进制.
    {
        trans(num,15,4);
    }


  二维数组

格式的第一种写法:

int[][]   arr  =  new   int[ 3][ 2];

定义了名称为arr的二维数组;
二维数组中有3个一维数组;
每一个一维数组中有2个元素;
一维数组的名称分别为arr[0],  arr[1],  arr[2];
 给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;


格式的第二种写法:

int[][] arr=new int[3][];//可以只定义二维数组中有几个一维数组,但没有定义每个一维数组的长度.

每一个一维数组的初始化值都是null.

可以单独给每一个一维数组定义长度.

public static void main(String[] args)
    {
        int[][] arr=new int[3][];
        arr[0] = new int[3];
        arr[1] = new int[1];
        arr[2] = new int[2];
        System.out.println(arr[1]);
    }

结果是[I@b5dac4,因为每个一维数组定义了长度,所以结果是一维数组的地址值,而不是null.

给一维数组定义完长度之后,可以打印出一维数组的长度:

system.out.println(arr[0].length);


格式的第三种写法:

int[][] arr={{},{},{}};


另外一维和二维数组还有其他写法,注意空格的位置.需要注意在实际开发中很少会用这么别扭的写法,这个仅作为sun认证的考试题出现.

int[] x;int x[];

int[][] x;int x[][];int[] x[];


例如:

1.

public static void main(String[] args)
    {
        int[][] arr=new int[3][2];
        System.out.println(arr);
    }

结果是[[I@b5dac4,表示的是打印的二维数组的地址值,注意开头的两个[[表示是二维数组.

2.

public static void main(String[] args)
    {
        int[][] arr=new int[3][2];
        System.out.println(arr[0]);
    }

结果是[I@b5dac4,表示打印的是二维数组的第一个一维数组的地址值,注意开头变成了一个[.

3.

public static void main(String[] args)
    {
        int[][] arr=new int[3][];
        System.out.println(arr[0]);
    }

结果是null.因为没有定义每个一维数组的长度,所以结果就是初始化值null.但是如果是指定了长度的数组,那么每个数组的元素初始化值是0.

比如:

public static void main(String[] args)
    {
        int[] arr=new int[3];
        System.out.println(arr[1]);
    }

结果是0.

4.需求:已知公司每个部门的销售业绩,求总销售额.

public static void main(String[] args)
    {
        int[][] arr={{1,4,6,7},{3,5,8,9},{2,5,7,4}};
        int sum=0;
        for(int x=0;x<arr.length;x++)
        {
            for(int y=0;y<arr[x].length;y++)
            {
                sum=sum+arr[x][y];
            }                
        }
        System.out.println("sum="+sum);
    }

5.下列那个选项是对的

已知int[] x,y[];//其实就是int[] x;int[] y[];所以x是一维数组,y是二维数组.

a.

x[0]=y;//错误,一维数组的一个元素不能等于一个二维数组.

b.

y[0]=x;//正确.

c.

y[0][0]=x;//错误.

d.

x[0][0]=y;//错误

e.

y[0][0]=x[0];//正确

f.

x=y;//错误









---------------------- android培训java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值