→阿童沐

財富==支撐一個人生存多長時間的能力!

导航

<Java SE 详解>数组-二分查找-

1、数组(Array):相同类型数据的集合就叫做数组.

2、如何定义一个数组:

  1>

package cn.edu.bupt.array;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = new int[4]; //定义数组的格式
}
}

从new可以看书,数组是一种对象类型.

type[] var = new type[len];


  2>

package cn.edu.bupt.array;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = {1, 2, 3, 4};
for (int i=0; i<a.length; i++)
{
System.out.println(a[i]);
}
}
}

  3>

package cn.edu.bupt.array;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = new int[]{1, 2, 3, 4};  //这里第二个int[]方括号内不能加入数组元素的个数,否则会编译错误
for (int i=0; i<a.length; i++)
{
System.out.println(a[i]);
}
}
}

java中的每个数组对象都有一个名为length的属性,表示数组的长度。

length属性是publicfinal属性,无法修改其值。数组长度是在构造数组的时候在构造函数中确定的,一旦确定,就无法改变其大小。

 


3.

package cn.edu.bupt.array;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a.equals(b)); //print false
}
}

这里a数组和b数组指向了不同的内存地址,而不是想String那样存在一个String Pool,因此使用继承过来的equals方法比较的两个引用地址的值时不相同的。

int[] a = new int[4],其中a是一个引用,它指向了生成的数组对象的首地址,数组中每个元素都是int类型,其中仅仅存放数据本身

注意:Java中内存堆中的对象是不能直接进行操作的,而必须通过引用进行操作,而new关键字创建对象完成后就是返回了该对象的引用;因此在创建对象数组的时候,每个数组元素实际是一个引用变量,而不是堆内存中的对象。

 


关于数组的协变性:

  协变的意义:当数组中的元素的类型时另一个数组的元素类型的子类的时候,该数组也是另一个数组的子类,这种意义就是数组的协变性;(泛型就不存在这种意义

  如下例:

package cn.edu.bupt.observer.observable;

public class ArrayShiftTest
{
    public static void main(String[] args)
    {
        Number[] nums;
        Integer[] ints;
        
        ints = new Integer[2];
        nums = ints;                    // 自动类型转换成为父类数组, OK
        System.out.println(ints instanceof Number[]);            // print true
        
        System.out.println("------------");
        nums = new Number[2];
        ints = (Integer[])nums;            // 强制转换成为子类型数组, OK    但运行时会发生错误
    }
}

 

  但是对于存在数组协变性的问题来说,更通常的做法是在遍历数组的时候取出数组中的每一个元素,对元素对象进行转换,这样避免了数据操作的不一致性;

  具体关于协变的问题,请参见本博客关于泛型的讲解;

 


4.二维数组

package cn.edu.bupt.array;

public class ArrayStart
{
public static void main(String[] args)
{
int[][] i = new int[2][3];
System.out.println(i instanceof Object); //print true
System.out.println(i[0] instanceof int[]); //print true
}
}

注意:int[]是一种类型,代表一维数组类型,同样int[][]是二维数组类型,依此类推.

package cn.edu.bupt.array;

public class ArrayStart
{
public static void main(String[] args)
{
//二维数组初始化
int[][] a = new int[][]{
{1, 2, 3},
{4, 5},
{6, 7, 8, 9, 10}
};

for (int i=0; i<a.length; i++)
{
for (int j=0; j<a[i].length; j++)
{
System.out.print(a[i][j] + ",");
}
System.out.println();
}
}
}

其中,a.length是数组高维的长度,a[i].length是数组的指定低维的长度.


不使用中间变量实现两个整数的交换:

int a = 3;
int b = 4;

a = a + b;
b = a - b;
a = a - b;

System.out.println(a);
System.out.println(b);

package cn.edu.bupt.array;

public class ArrayStart
{
public static void main(String[] args)
{
I[] i = new I[]{new C(), new C()}; //含有两个引用元素的数组,这两个引用指向I类
}
}

interface I
{

}

class C implements I
{

}

java.util.Arrays相关函数用法: 


判断数组相等的方法,java.util.Arrays

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = new int[]{1, 2, 3};
int[] b = new int[]{1, 2, 3};

System.out.println(Arrays.equals(a, b));

}
}

数组copy

JDK中提供了两种类型的copy方法:

1.java.lang.System.arraycopy

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = new int[]{1, 2, 3};
int[] b = new int[3];

System.arraycopy(a, 0, b, 0, 3);
for (int i=0; i<3; i++)
{
System.out.println(b[i]);
}
}
}

此处注意的是:目标数组b一定需要预先分配好空间,否则会发生异常。

2.java.util.Arrays.copyof

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = new int[]{1, 2, 3};
int[] b = null;

b = Arrays.copyOf(a, 2);
for (int i=0; i<2; i++)
{
System.out.println(b[i]);
}
}
}

注意:同System.arraycopy方法不一样的是,目标数组b可以在调用处不分配空间,而是在copyof方法内部分配了数组的空间,在调用处需要做的工作是仅仅是声明一个数组的引用变量来接受copy好的数组。


三维数组:

type[][][] var = new type[m][n][k];

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart
{
public static void main(String[] args)
{
int[][][] a = new int[2][3][4];
System.out.println(a instanceof int[][][]);
System.out.println(a[0] instanceof int[][]);
System.out.println(a[0][0] instanceof int[]);

for (int[][] b : a)
{
for (int[] c : b)
{
for (int d : c)
{
System.out.print(d);
}
System.out.println();
}
System.out.println("------------");
}
}
}

冒泡排序:

package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = {4,5,6,3,9,5,4,6,8,0};
ArrayStart.bubbleSort(a);
for (int b : a)
{
System.out.println(b);
}
}

private static void bubbleSort(int[] a)
{
int temp = 0;
for (int i=a.length-1; i>0; i--)
{
for (int j=0; j<i; j++)
{
if (a[j] > a[j+1])
{
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
}
package cn.edu.bupt.array;

import java.util.Arrays;

public class ArrayStart
{
public static void main(String[] args)
{
int[] a = {4,5,6,3,9,5,4,6,8,0};
ArrayStart.bubbleSort(a);
for (int b : a)
{
System.out.println(b);
}
}

private static void bubbleSort(int[] a)
{
int temp = 0;
for (int i=0; i<a.length-1; i++)
{
for (int j=0; j<a.length-i-1; j++)
{
if (a[j] > a[j+1])
{
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
}

 


二分查找(binary search):

二分查找的条件是:待查找的数组首先需要有序。

二分查找一般使用递归方法:

package cn.edu.bupt.array;


public class ArrayStart
{
public static void main(String[] args)
{
int[] a = new int[] { 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 15, 16, 19, 22,
23, 25, 27 };
int value = 14;
int index = binarySearch(a, 0, a.length-1, value);
System.out.println(index);
}

private static int binarySearch(int[] a, int startIndex, int endIndex, int value)
{
if (startIndex > endIndex)
{
return -1;
}
int index = (startIndex + endIndex) / 2;
if (value == a[index])
{
return index;
}
else if (value > a[index])
{
return binarySearch(a, index + 1, endIndex, value);
}
else
{
return binarySearch(a, startIndex, index - 1, value);
}

}
}

二分查找的非递归方法:

package cn.edu.bupt.array;


public class ArrayStart
{
public static void main(String[] args)
{
int[] a = new int[] { 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 15, 16, 19, 22,
23, 25, 27 };
int value = 17;
int index = binarySearch(a, value);
System.out.println(index);
}

private static int binarySearch(int[] a, int value)
{
int startIndex = 0;
int endIndex = a.length - 1;
int middle = 0;

while (startIndex <= endIndex)
{
middle = (startIndex + endIndex) / 2;
if (value == a[middle])
{
return middle;
}
else if (value < a[middle])
{
endIndex = middle - 1;
}
else
{
startIndex = middle + 1;
}
}
return -1;
}
}

题目:

随机生成 50 个数字(整),每的范围是 [10, 50],统计每个数字出现的次以及 出现次数以及出现次数最多的数字与他的个数,最后将每个数字以及其出现的次数打印出来,如果某个数字出现的次数为0,则不要打印它,打印时按照数字的生序排列。

package cn.edu.bupt.array;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class RandomNumArray
{
public static void main(String[] args)
{
RandomArray ra = new RandomArray(50);
List<NumStruct> list = ra.generateRandomArrayWithNums();

for (NumStruct ns : list)
{
System.out.println(ns.getNum() + "==>" + ns.getTimes());
}
}

}

class RandomArray
{
public RandomArray(int arrayLen)
{
this.randomArray = new int[arrayLen];
this.sortResult = new LinkedList<NumStruct>();
}

public List<NumStruct> generateRandomArrayWithNums()
{
//生成随机数
for (int i=0; i<this.randomArray.length; i++)
{
this.randomArray[i] = (int)(Math.random() * 41 + 10);
}
//对数组进行排序
Arrays.sort(this.randomArray);
for (int i=0; i<this.randomArray.length; i++)
{
System.out.print(this.randomArray[i] + " ");
}
System.out.println();

//统计随机数
int counter = 0;
for (int i=0; i<this.randomArray.length; i++)
{
counter = 1;
System.out.println(this.randomArray[i]);
for (int j=i+1; j<this.randomArray.length && this.randomArray[j] == this.randomArray[i]; j++)
{
System.out.println(this.randomArray[j]);
counter++;
i++;
}
this.sortResult.add(new NumStruct(this.randomArray[i], counter));
}

return this.sortResult;

}

//private field
private int[] randomArray = null;
private List<NumStruct> sortResult = null;

}

class NumStruct
{
//constructor
public NumStruct(int num, int times)
{
super();
this.num = num;
this.times = times;
}

//getter and setter
public int getNum()
{
return num;
}
public int getTimes()
{
return times;
}

//private field
private int num;
private int times;


}













posted on 2012-03-17 10:31  阿童沐  阅读(417)  评论(0)    收藏  举报