数组的学习

主要内容

  1. 数组的定义
  2. 数组的 4 个特点
  3. 数组的遍历、拷贝
  4. 多维数组
  5. 表格数据的存储
  6. 冒泡排序
  7. 二分法查找(折半查找)

第一节 数组的概念

1.1 数组的定义

数组的定义

数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问它们。数组的四个基本特点:

  1. 长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
  2. 其元素的类型必须是相同类型,不允许出现混合类型。
  3. 数组类型可以是任何数据类型,包括基本类型和引用类型。
  4. 数组变量属于引用类型,数组也是对象。

注: 数组变量属于引用类型,数组也是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java 中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中存储的。

1.2 创建数组和初始化

       数组的创建和初始化是数组使用的第一步,我们通过内存分析也让大家更深入的了解数组。同时,通过内存分析更加明白数组的本质其实还是“对象”。

1.2.1 数组声明      

type[ ]     arr_name; //方式一(推荐使用这种方式)

type       arr_name[ ]; //方式二

例1,创建基本类型一维数组

public class Test {
public static void main(String args[ ]) {
int[ ] s = null; // 声明数组;
s = new int[10]; // 给数组分配空间;
for (int i = 0; i < 10; i++) {
s[i] = 2 * i + 1;//给数组元素赋值; 数组是对象,数组中的元素就是对象的属性
System.out.println(s[i]);
}
}
}

例2 创建引用类型一维数组

class Man{
    private int age;
    private int id;
    public Man(int id,int age) {
        super();
        this.age = age;
        this.id = id;
    }
}
public class AppMain {
    public static void main(String[ ] args) {
        Man[ ] mans;	//声明引用类型数组;
        mans = new Man[10];	//给引用类型数组分配空间;

        Man m1 = new Man(1,11); Man m2 = new Man(2,22);

        mans[0]=m1;//给引用类型数组元素赋值;
        mans[1]=m2;//给引用类型数组元素赋值;
    }
}

1.2.2 初始化

        数组的初始化方式总共有三种:静态初始化、动态初始化、默认初始化。下面针对这三种方式分别讲解。

1.2.1.1 静态初始化

        除了用 new 关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

int [ ] a = { 1, 2, 3 };// 静态初始化基本类型数组;

Man[ ] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;

1.2.1.2 动态初始化

int[ ] a1 = new int[2];//动态初始化数组,先分配空间;
a1[0]=1;//给数组元素赋值;
a1[1]=2;//给数组元素赋值;

1.2.1.3 默认初始化

        数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

int a2[ ] = new int[2]; // 默认值:0,0
boolean[ ] b = new boolean[2]; // 默认值:false,false String[ ] s = new String[2]; //  默认值:null, null

第二节 数组常见操作

        数组创建后,我们经常需要对数组做两种最常见的操作:遍历、拷贝。遍历指的就是“通过循环遍历数组的所有元素”。

2.1 数组的遍历

        数组元素下标的合法区间:[0, length-1]。我们可以通过下标来遍历数组中的元素,遍历时可以读取元素的值或者修改元素的值。

例3

public class test01 {
	public static void main(String[] args) {
		//数组的定义和初始化
		int[] arr1=new int[5];
		System.out.println(arr1[0]);
		System.out.println(arr1[1]);
		
		int arr2[]= {20,30,40};   //静态初始化
		System.out.println(arr2);
		
		//数组的遍历
		for(int i=0;i<5;i++) {
			arr1[i]=i*2+1;
		}
		for(int i=0;i<arr1.length;i++) {
			System.out.println(arr1[i]);
		}
		
	}

}

2.2 for-each循环

        增强 for 循环 for-each 是 JDK1.5 新增加的功能,专门用于读取数组或集合中所有的元素,即对数组进行遍历。

例4 使用增强for 循环遍历数组

public class Test {

    public static void main(String[ ] args){

        String[ ] ss = { "aa", "bbb", "ccc", "ddd" }; 

        for (String temp : ss) {

        System.out.println(temp);

    }

}

注: 

  1. for-each 增强 for 循环在遍历数组过程中不能修改数组中某元素的值。
  2. for-each 仅适用于遍历,不涉及有关索引(下标)的操作。

2.3 数组的拷贝

        System 类里也包含了一个 static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,该方法可以将 src 数组里的元素值赋给 dest 数组的元素,其中 srcpos 指定从 src 数组的第几个元素开始赋值,length 参数指定将 src 数组的多少个元素赋给 dest 数组的元素。

例5

public class test03 {
	public static void main(String[] args) {
		String[] s= {"阿里","尚学堂","京东","搜狐","网易"};
		String[] sBak=new String[6];
		System.arraycopy(s,0,sBak,0,s.length);
		for(int i=0;i<sBak.length;i++) {
			System.out.println(sBak[i]+"\t");
		}
	}

}

2.4 Java.util.Arrays类

        JDK 提供的 java.util.Arrays 类,包含了常用的数组操作,方便我们日常开发。Arrays类包含了:排序、查找、填充、打印内容等常见的操作。

例6 使用Arrays 类对数组元素进行排序,实现二分查找,对数组进行填充。

import java.util.Arrays;

public class test04 {
	
	
	//对数组元素进行排序
	public static void main(String args[]) {
		int[] a= {1,2,323,23,543,12,59};
		System.out.println(Arrays.toString(a));
		Arrays.sort(a);
		System.out.println(Arrays.toString(a));
		
		//实现二分查找法
		System.out.println("该元素的索引:"+Arrays.binarySearch(a,23));//返回排序后新的索引位置,若未找到返回负数。
		
		//使用Arrays类对数组进行填充
		
		Arrays.fill(a,2,4,100);//将2到4索引的元素替换为100; 
		System.out.println(Arrays.toString(a));
	}
	
	
}

第三节 多维数组

3.1 多维数组

        多维数组可以看成以数组为元素的数组。可以有二维、三维、甚至更多维数组,但是实际开发中用的非常少。最多到二维数组。

例7 二维数组的声明

public class Test {
    public static void main(String[ ] args) {
        // Java中多维数组的声明和初始化应按从低维到高维的顺序进行
        int[ ][ ] a = new int[3][ ]; 
            a[0] = new int[2];
            a[1] = new int[4];
            a[2] = new int[3];
            // int a1[ ][ ]=new int[ ][4];//非法
    }
}

3.2 数组存储表格数据

例8 使用二维数组存储表格数据

import java.util.Arrays;

public class test05 {
	/**
	 *二维数组的练习
	 *使用Object[][]存储整个表格的数据
	 */
	public static void main(String[] args) {
		Object[] emp0= {1001,"背包客",18,"程序员","2019-12-9"};
		Object[] emp1= {1002,"彼岸花",23,"程序员","2019-12-9"};
		Object[] emp2= {1003,"背包客",21,"程序员","2019-12-9"};
		
		Object[][] emps=new Object[3][];
		emps[0]=emp0;
		emps[1]=emp1;
		emps[2]=emp2;
		
		//打印二维数组的内容(表格数据打印)
		
		for(int i=0;i<emps.length;i++) {
			System.out.println(Arrays.toString(emps[i]));
		}
		
		
		//使用嵌套循环打印二维数组(打印表格数据)
		for(int i=0;i<emps.length;i++) {
			for(int j=0;j<emps[i].length;j++) {
				System.out.print(emps[i][j]+"\t");
			}
			System.out.println();
		}
		
	}
}

例9 使用javabean 和一维数组保存表格信息


	//使用javabean和数组存储表格的信息
public class test06 {
	public static void main(String[] args) {
		Emp emp0=new Emp(1001,"彼岸花",18,"程序员","2019-9-9");
		Emp emp1=new Emp(1002,"背包客",33,"程序员","2019-9-9");
		Emp emp2=new Emp(1003,"即兴",21,"程序员","2019-9-9");
		
		Emp[] emps=new Emp[3];
		emps[0]=emp0;
		emps[1]=emp1;
		emps[2]=emp2;
		
		//遍历数据
		for(int i=0;i<emps.length;i++) {
			System.out.println(emps[i]);
		}
	}

}


class Emp{
	private int id;
	private String name;
	private int age;
	private String job;
	private String heredate;
	
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return getId()+"\t"+getName()+"\t"+getAge()+"\t"+getJob()+"\t"+getHeredate();
	}
	public Emp() {}
	
	public Emp(int id, String name, int age, String job, String heredate) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.job = job;
		this.heredate = heredate;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public String getHeredate() {
		return heredate;
	}
	public void setHeredate(String heredate) {
		this.heredate = heredate;
	}
	
	
}

第四节 常见算法

4.1 冒泡排序

        

冒泡排序算法重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,这样越大的元素会经由交换慢慢“浮”到数列的顶端。

冒泡排序算法的运作如下:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

 例10 冒泡排序的基础算法

import java.util.Arrays;
public class test07 {
	public static void main(String[] args) {
		int[] values= {3,5,1,7,9,2,0,21,19};
		bubbleSort(values);
		System.out.println(Arrays.toString(values));
	}
	
	
	public static void bubbleSort(int[] values) {
		int temp;
		for(int i=0;i<values.length;i++) {
			for(int j=0;j<values.length-1-i;j++) {
				if(values[j]>values[j+1]) {
					temp=values[j];
					values[j]=values[j+1];
					values[j+1]=temp;
				}
			}
		}
	}

}

4.2 二分查找法

        

二分法检索(binary search)又称折半检索,二分法检索的基本思想是设数组中的元素从小到大有序地存放在数组array)中,首先将给定值 key 与数组中间位置上元素的关键码(key)比较,如果相等,则检索成功;否则,若 key 小,则在数组前半部分中继续进行二分法检索;若 key 大,则在数组后半部分中继续进行二分法检索。

这样,经过一次比较就缩小一半的检索区间,如此进行下去,直到检索成功或检索失败。二分法检索是一种效率较高的检索方法。比如,我们要在数组[7, 8, 9, 10, 12, 20, 30, 40, 50,

80, 100]中查询到 10 元素,过程如下:

 例11 二分法查找法的基本算法

import java.util.Arrays;
public class text08 {
	public static void main(String[ ] args) {
		int[ ] arr = { 30,20,50,10,80,9,7,12,100,40,8};
		int searchWord = 20; // 所要查找的数
		Arrays.sort(arr); //二分法查找之前,一定要对数组元素排序 System.out.println(Arrays.toString(arr));
		System.out.println(searchWord+"元素的索引: "+binarySearch(arr,searchWord));
	}

	public static int binarySearch(int[ ] array, int value){
		int low = 0;
		int high = array.length - 1;
		while(low <= high){
			int middle = (low + high) / 2;
			if(value == array[middle]){
				return middle;	//返回查询到的索引位置
			}
			if(value > array[middle]){ 
				low = middle + 1;
			}
		
			if(value < array[middle]){ 
				high = middle - 1;
			}
		}
		return -1;	//上面循环完毕,说明未找到,返回-1

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值