一、一维数组
(一)初始化
1、静态初始化:给出初始值,系统决定长度
int[] sArr = {1,2,3};
String[] sArrStr = {"a","b","c"};
2、动态初始化:只指定长度,系统给出初始值
int[] dArr = new int[3];//分配空间
dArr[0] = 1;
dArr[1] = 2;
dArr[2] = 3;
String[] dArrStr = new String[4];//分配空间
3、赋值操作:引用值的指向
public void test2(){
int[] arr1= new int[2];
arr1[0]= 0;
arr1[1]= 1;
System.out.println(arr1[0]);// 0
System.out.println(arr1[1]);// 1
System.out.println("*****************************");
int[] arr2 = arr1;//相当于把数组1的地址同样给了数组2
arr2[0] = 100;
arr2[1] = 200;
System.out.println(arr1[0]);//100
System.out.println(arr1[1]);//200
System.out.println(arr2[0]);//100
System.out.println(arr2[1]);//200
}
(二)内存分配
1、一个数组
2、多个数组:注意引用值的拷贝
(三)常见操作
/**
* 循环操作
*/
public void test3(){
int[] arr = {298,2,14,345,256,89,100,7};
//循环操作1
int len = arr.length;
for (int i = 0; i < len; i++) {
System.out.println(arr[i]);
}
System.out.println("-----------------------");
//循环操作2
for (int i : arr) {
System.out.println(i);
}
}
/**
* 获取最值
*/
public void test4(){
int[] arr = {298,2,14,345,256,89,100,7};
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
max = max > arr[i] ? max : arr[i];
}
System.out.println("数组中最大的值 : "+max);
}
/**
* 数组元素逆序
* [298, 2, 14, 345, 256, 89, 100, 7]
* [7, 100, 89, 256, 345, 14, 2, 298]
*/
public void test5(){
int[] arr = {298,2,14,345,256,89,100,7};
// 方法一:0和(length-1),1和((length-1-1)一次类推
for (int i = 0; i < arr.length/2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
//方法二
for (int start = 0,end=arr.length-1; start <= end; start++,end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
/**
* 数组查表法
*/
public void test6(){
String[] strArr = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
Scanner sc = new Scanner(System.in);//得到键盘输入
int index = sc.nextInt();
System.out.println("你要找的日期为 : " + strArr[index]);
}
/**
* 数组元素查找
*/
public void test7(){
int[] indexArr = {1,2,3,4,5,3};
int task = 3;
//基本查找
for (int i = 0; i < indexArr.length; i++) {
if(task == indexArr[i]){
System.out.println("下标为: " + i);
break;//加break的话,只取到第一次出现的索引
}
}
System.out.println(Arrays.binarySearch(indexArr, 3));//二分查找
}
/**
* int数据转成数组
*/
public static void jiamiDemo(){
//int数据转成数组
int number =1234567;//定义数据
int len = 8;
int[] arr = new int[len];//定义数组
//把数据中每一位上的数据获取后存储到数组中
// int index = 0;
// arr[index] = number%10;
// index++;
// arr[index] = number/10%10;
// .
// .
//利用取余获取每一位上的值
int index = 0;
while(number > 0) {
arr[index] = number%10;
index++;
number/=10;//一次获取位数的值
}
for (int i = 0; i < index; i++) {
System.out.print(arr[i]);
}
}
/**
* 简单拷贝
*/
public void test8() {
String[] arr = {"a","b","a","b","a4","b5"};
String[] copyArr;
// 浅拷贝:地址值(引用值).
// 即arr与copyArr指向【堆】同一个数组
copyArr = arr;
arr[3] = "9999999999";//指向同一个地址,修改arr,copyArr也会改变
System.out.println(Arrays.asList(copyArr));
// 深拷贝,指向不同的引用:
// 方法一:循环
copyArr = new String[arr.length];
for (int i = 0; i < arr.length; i++) {
copyArr[i] = arr[i];
}
arr[3] = "改值";//修改arr不影响
System.out.println(Arrays.asList(copyArr));
// 方法二:clone。
copyArr = arr.clone();
arr[2] = "22222";//修改不影响
System.out.println(Arrays.asList(copyArr));
// 方法三:arraycopy()。
// copyArr = new String[arr.length];//不new 一个,则是浅拷贝;new一个则为深拷贝。
System.arraycopy(arr, 0, copyArr, 0, arr.length);
arr[2] = "22222888";
System.out.println(Arrays.asList(copyArr));
// 方法四:Arrarys类的copyOf()方法与copyOfRange()方法可实现对数组的复制
copyArr = Arrays.copyOf(arr, arr.length);
copyArr = Arrays.copyOfRange(arr, 0, arr.length);
arr[4] = "12345";
System.out.println(Arrays.asList(copyArr));
}
/**
* 数组的拷贝
* 1,2 拷贝到 3
*/
public void test9(){
String[] arr = {"a","b","a","b"};
String[] arr2 = {"1","2","3"};
int len = arr.length;
int len2 = arr2.length;
String[] copyArr = new String[len+len2];
// 方法一:使用System.arraycopy()方法
System.arraycopy(arr, 0, copyArr, 0, len);
System.arraycopy(arr2, 0, copyArr, len, len2);
// 方法二:循环
for (int i = 0; i < len; i++) {
copyArr[i] = arr[i];
}
for (int i = 0; i < len2; i++) {
copyArr[len+i] = arr2[i];
}
System.out.println(Arrays.asList(copyArr));
// 方法三:ArrayList
List list = new ArrayList();
for (int i = 0; i < len; i++) {
list.add(arr[i]);
}
for (int i = 0; i < len2; i++) {
list.add(arr2[i]);
}
Object [] aa = list.toArray();//利用List的toArray()方法
System.out.println(Arrays.asList(aa));
}
二、二维数组
(一)初始化
1、动态初始化
1)格式1
int[][] arr = new int[3][2];
2)格式2
int[][] arr2 = new int[2][];
arr2[0] = new int[2];
arr2[1] = new int[3];
2、静态初始化
int[][]arr3 = {{1,2},{3,4,5}};
(二)内存图解
1、动态初始化1
2、动态初始化2
3、静态初始化:自动会new一维数组。
(三)简单操作
/**
* 遍历
*/
private void test2() {
int[][] arr = {{1,2},{3,4,5},{6,7,8,9}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
System.out.println("*****************************************************8");
}
/**
* 求和
*/
private void test3() {
int[][] arr = {{1,2},{3,4,5},{6,7,8,9}};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum += arr[i][j];
}
}
System.out.println("求和: " + sum);
}
/**
* 杨辉三角
* 任何一行的第一列和最后一列都是1
* 从第三行开始,每一个数据时它上一行的前一列和它上一行的本列之和,最后一列除外。
* 1
* 1 1
* 1 2 1
* 1 3 3 1
* 1 4 6 4 1
* 1 5 10 10 5 1
*/
public void test4(){
//创建键盘录入对象
Scanner scanner = new Scanner(System.in);
// 这个n的数据来自键盘录入
int n = scanner.nextInt();
//定义一个二维数组
int[][] arr = new int[n][n];
// 给这个二维数组任何一行的第一列和最后一列赋值1
for (int i = 0; i < arr.length; i++) {
arr[i][0] = 1;//任何一行第1列
arr[i][i] = 1;//任何一行最后1列
}
// 从第三行开始,每一个数据时它上一行的前一列和它上一行的本列之和,最后一列除外。
// 第3行,第2列开始,所以i=2,j=1开始
for (int i = 2; i < arr.length; i++) {
// 不能取最后一列,所以减去1,j <= i-1
for (int j = 1; j <= i-1; j++) {
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
}
}
//遍历二维数组
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j <= i; j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
三、数组高级
(一)排序算法(介绍被面试过的2种)
1、冒泡排序(被面到过好几次,如上海安硕(信贷系统)、科沃斯)
1)原理:相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处。同理,继续,即可得到一个排好序的数组。
2)分析图:
3)代码实现
/**
* 冒泡排序:
* 数组排序之冒泡排序:
* 相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处
*
* 外循环:一共是 arr.length-1 次循环循环
* 内循环:每次循环都会少一次
*
* 两两比较,大的往后放
* 总共需要比较数组长度的 -1 次。(外层循环)
* 每一个比较完毕后,下一次比较的时候就会少一个元素的比较(内层循环)
*/
private void test1() {
// 定义一个数组
int[] arr = { 24, 69, 80, 57, 13 };
System.out.println("排序前:");
printArray(arr);
// 第一次比较
// arr.length - 1是为了防止数据越界
// arr.length - 1 - 0是为了减少比较的次数
/* for (int x = 0; x < arr.length - 1 - 0; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println("第一次比较后:");
printArray(arr);*/
// 第二次比较
// arr.length - 1是为了防止数据越界
// arr.length - 1 - 1是为了减少比较的次数
/* for (int x = 0; x < arr.length - 1 - 1; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println("第二次比较后:");
printArray(arr);*/
//排序
/* for (int x = 0; x < arr.length - 1; x++) {
for (int y = 0; y < arr.length - 1 - x; y++) {
if (arr[y] > arr[y + 1]) {
int temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;
}
}
}*/
for (int i = 0; i < arr.length-1; i++) {//总共需要比较数组长度的 -1 次。(外层循环)
for (int j = 0; j < arr.length-1-i; j++) {//每一个比较完毕后,下一次比较的时候就会少一个元素的比较(内层循环)
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println("冒泡排序后:");
printArray(arr);
}
2、选择排序
2)分析图
3)代码实现
/**
* 选择排序
* 从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
*/
private void test2() {
// 定义一个数组
int[] arr = { 24, 69, 80, 57, 13 };
System.out.println("排序前:");
printArray(arr);
/*
// 第一次
int x = 0;
for (int y = x + 1; y < arr.length; y++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("第一次比较后:");
printArray(arr);
// 第二次
x = 1;
for (int y = x + 1; y < arr.length; y++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("第二次比较后:");
printArray(arr);
*/
for (int i = 0; i < arr.length-1; i++) {//从0索引开始,
for (int j = i+1; j < arr.length; j++) {//依次和后面元素比较,
if(arr[j] < arr[i] ){//小的往前放
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
printArray(arr);
}
3、实例操作:把字符串中的字符进行排序。
/*
* 把字符串中的字符进行排序。
* 举例:"dacgebf"
* 结果:"abcdefg"
*
* 分析:
* A:定义一个字符串
* B:把字符串转换为字符数组
* C:把字符数组进行排序
* D:把排序后的字符数组转成字符串
* E:输出最后的字符串
*/
private void test3() {
String str = "mkloiuytrfdgsa";
char[] strArr = str.toCharArray();
//选择排序
/* for (int i = 0; i < strArr.length-1; i++) {//从0索引开始,
for (int j = i+1; j < strArr.length; j++) {//依次和后面元素比较,
if(strArr[j] < strArr[i]) {//小的往前放
char temp = strArr[j];
strArr[j] = strArr[i];
strArr[i] = temp;
}
}
}*/
//冒泡排序
for (int i = 0; i < strArr.length-1; i++) {//每次从0开始,一共是length-1次
for (int j = 0; j < strArr.length-1-i; j++) {//每次就会少一次
if(strArr[j] > strArr[j+1]) {//大的往后放
char temp = strArr[j+1];
strArr[j+1] = strArr[j];
strArr[j] = temp;
}
}
}
String sortStr = String.valueOf(strArr);
System.out.println(sortStr);//adfgiklmorstuy
}
(二)查找算法
1、基本查找算法
1)对象:针对没有顺序的数组
/**
* 查找
* 基本查找:数组元素无序(从头找到尾)
*/
private void test4() {
//定义一个数组
int[] arr = {55,22,11,44,33,88,66};//没顺序的数组
int a = 33;
int index = -1;
for (int i = 0; i < arr.length; i++) {//循环整个数组,依次比较
if(arr[i]==a) {
System.out.println("索引为" + i);
index = i;
break;
}
}
if(index == -1){
System.out.println("没找到....");
}
}
2、二分查找算法
1)对象:针对有顺序的数组
/**
* 二分查找
* * 分析:
* A:定义最大索引,最小索引
* B:计算出中间索引
* C:拿中间索引的值和要查找的值进行比较
* 相等:就返回当前的中间索引
* 不相等:
* 大 左边找
* 小 右边找
* D:重新计算出中间索引
* 大 左边找
* max = mid - 1;
* 小 右边找
* min = mid + 1;
* E:回到B
*/
public void test5() {
int[] arr = {11,22,33,44,55,66,77};
int value = 0;
//定义最大索引,最小索引
int max = arr.length -1;
int min = 0;
//计算出中间索引
int mid = (max +min)/2;
//拿中间索引的值和要查找的值进行比较
while(arr[mid] != value){
if(arr[mid]>value){//中间值大,向左找;这时最大值为这个(中间值-1),最小值为0
max = mid - 1;
}else if(arr[mid] max){
mid = -1;
break;//找不到
}
mid = (max +min)/2;
}
System.out.println("二分查找后的结果: "+ mid);
}
5)注意问题:一个无序数组,先排序,再使用二分查找,这是不行的。
package array;
/**
*
* @Title: 使用二分排序的问题
* @Description:
* @Copyright: Copyright (c) 2015
* @Company:
*
* @author: SAM-SHO
* @version: 1.0
* @CreateDate:Apr 9, 2015
*/
/*
* 注意:下面这种做法是有问题的。
* 因为数组本身是无序的,所以这种情况下的查找不能使用二分查找。
* 你先排序了,但是你排序的时候已经改变了我最原始的元素索引,所以查找出来的不是原有需要的索引了。
*/
public class ArrayDemo2 {
public static void main(String[] args) {
// 定义数组
int[] arr = { 24, 69, 80, 57, 13 };
// 先排序
bubbleSort(arr);
// 后查找
int index = getIndex(arr, 80);
System.out.println("index:" + index);
}
// 冒泡排序代码
public static void bubbleSort(int[] arr) {
for (int x = 0; x < arr.length - 1; x++) {
for (int y = 0; y < arr.length - 1 - x; y++) {
if (arr[y] > arr[y + 1]) {
int temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;
}
}
}
}
// 二分查找
public static int getIndex(int[] arr, int value) {
// 定义最大索引,最小索引
int max = arr.length - 1;
int min = 0;
// 计算出中间索引
int mid = (max + min) / 2;
// 拿中间索引的值和要查找的值进行比较
while (arr[mid] != value) {
if (arr[mid] > value) {
max = mid - 1;
} else if (arr[mid] < value) {
min = mid + 1;
}
// 加入判断
if (min > max) {
return -1;
}
mid = (max + min) / 2;
}
return mid;
}
}
(三)数组工具类
1、Arrays
1)把数组转成字符串:public static String toString(int[] a)
package array;
import java.util.Arrays;
/**
*
* @Title: Arrays工具类的使用
* @Description:
* @Copyright: Copyright (c) 2015
* @Company:
*
* @author: SAM-SHO
* @version: 1.0
* @CreateDate:Apr 9, 2015
*/
/*
* Arrays:针对数组进行操作的工具类。比如说排序和查找。
* 1:public static String toString(int[] a) 把数组转成字符串
* 2:public static void sort(int[] a) 对数组进行排序
* 3:public static int binarySearch(int[] a,int key) 二分查找
*/
public class ArraysDemo {
public static void main(String[] args) {
// 定义一个数组
int[] arr = { 24, 69, 80, 57, 13 };
// public static String toString(int[] a) 把数组转成字符串
System.out.println("排序前:" + Arrays.toString(arr));
// public static void sort(int[] a) 对数组进行排序
Arrays.sort(arr);
System.out.println("排序后:" + Arrays.toString(arr));
// [13, 24, 57, 69, 80]
// public static int binarySearch(int[] a,int key) 二分查找
System.out.println("binarySearch:" + Arrays.binarySearch(arr, 57));
System.out.println("binarySearch:" + Arrays.binarySearch(arr, 577));
}
}
2、Array-反射使用