1.数组
数组在是在一段连续内存空间内存储多个相同数据类型数据的有序集合。
数组的特点:
- 是一个引用数据类型
- 存储的多个数据类型要求数据类型相同
- 数组的长度一旦确定,不可改变
- 有序性,数组中的每一个空间的序号,从0开始,每次+1——>索引
1.1数组的声明
- 数据类型 [] 数组名;
- 数据类型 数组名[];
注意:数组中的每一个空间如果没有赋值,存在默认值,由数组的类型决定,引用数据类型是null,整数是0,小数是0.0,布尔类型是false,字符是’ '。
1.2数组初始化
动态初始化 : 先创建数组,然后再赋值
- 数据类型[] 数组名 = new 数据类型[数组的长度];
- 数据类型: 可以为任意数据类型;
- 数组的长度 : 必须为整数,0或者以上的正整数;
静态初始化 : 创建数组的同时赋值
- 数据类型[] 数组名 = new 数据类型[]{数据1,数据2,数据3…};
- 数据类型[] 数组名 = {数据1,数据2,数据3…};
public class Test02 {
public static void main(String[] args) {
//数组的声明 先声明后赋值
int[] arr = new int[3];//[]中的数字表示数组的长度
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
//数组声明同时赋值
int[] arr2 = new int[]{1,2,3,4,5};
}
}
注意:数组的引用同一时刻只能指向一个地址。
1.3数组遍历
要想获取数组中的所有数据需要使用普通for循环或者增强for循环:
普通for循环:循环条件i作为数组的索引,确定索引变化的范围;
增强for循环——foreach:
for(数据类型 变量名:数组名|容器名){
变量名:存放数据中的每一个数据,不是索引,是数据
}
foreach更简单,但是for循环的遍历更强大。
public class ArrayDemo02 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
//for遍历
for(int i=0;i<=arr.length-1;i++){
System.out.println(arr[i]);
}
//foreach
for (int i:arr ) {
System.out.println(i);
}
}
}
数组练习:
public class ArrayTest03 {
public static void main(String[] args){
int[] arr1 = new int[]{1,2,3};
a1(arr1);
a3(arr1);
}
//A:遍历int类型的数组 依次输出每个数组元素
public static void a1(int[] arr1){
for (int i:arr1
) {
System.out.println(i);
}
}
//B:遍历字符数组
public static void a2(char[] arr1){
for (char i:arr1
) {
System.out.println(i);
}
}
//C:最值:获取数组中的最大值和最小值
public static void a3(int[] arr1){
int max = arr1[0] ;
int temp2 = 0;
for(int i=1;i<arr1.length;i++){
if(arr1[i]>=arr1[0]){
max = arr1[i];
}
}
System.out.println("最大值是:"+max);
for(int i=1;i<arr1.length;i++){
if(arr1[i]<=arr1[0]){
arr1[0] = arr1[i];
}
}
System.out.println("最小值是:"+arr1[0]);
}
//D:逆序:倒叙输出数组元素
public static void a4(int[] arr1){
for(int i =arr1.length-1;i>0;i--){
System.out.println(arr1[i]);
}
}
}
1.4数组异常
在使用数组时,我们会遇到一些异常:
1.空指针异常——NullPointerException
数组引用没有指向一个数组对象,指向为空null;
2.数组索引越界异常——ArrayIndexOutOfBoundsException
索引为负数或索引大于等于数组长度
public class ArrayDemo04 {
public static void main(String[] args) {
int[] arr = {};
System.out.println(arr.length);
//数组索引越界
System.out.println(arr[0]);
}
}
数组练习2:
public class ArrayTest05 {
public static void main(String[] args) {
int [] arr = new int[]{1,8,67,456,34};
System.out.println(index(arr,999));
}
/*1.数组元素查找(查找指定元素第一次在数组中出现的索引)
* 若存在:返回这个元素的下标
* 若不存在:返回-1
*/
public static int index(int[] arr,int member){
int num =0;
for(int i = 0;i<arr.length;i++){
if(member == arr[i]){
num = i;
}else{
num = -1;
}
}
return num;
}
//2.将一个存放了大写字母的数组转换成存放小写字母的数组返回
public static char[] change(char[] arr){
for(int i=0;i<=arr.length-1;i++){
//如果字符不是A~Z之间的字符不变
if(arr[i]>='A' && arr[i]<='Z'){
arr[i]+=32;
}
}
return arr;
}
}
定义一个数组存储班级所有学生信息,求出班级学生身高的值(去重),以及最高身高:
//学生类
public class Student {
private int num;
private String name;
private int age;
private int heigth;
public int getHeigth() {
return heigth;
}
public void setHeigth(int heigth) {
this.heigth = heigth;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
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 Student(int num, String name, int age,int heigth) {
this.num = num;
this.name = name;
this.age = age;
this.heigth = heigth;
}
public Student() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return num == student.num &&
age == student.age &&
Objects.equals(name, student.name);
}
@Override
public String toString() {
return "Student{" +
"num=" + num +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
//测试类
public class Test {
public static void main(String[] args) {
//新建学生对象
Student s1 = new Student(100,"兔子",18,180);
Student s2 = new Student(101,"鹰",5,178);
Student s3 = new Student(102,"熊",10,175);
Student s4 = new Student(103,"猪",8,178);
Student s5 = new Student(104,"狗",12,175);
Student s6 = new Student(105,"羊",15,160);
Student s7 = new Student(106,"牛",18,180);
//新建学生数组
Student[] s = new Student[]{s1,s2,s3,s4,s5,s6,s7};
System.out.println(s[0]);
//调用方法求最高身高
System.out.println("身高最高的是:"+getMax(s));
//调用方法求身高的值
getH(s);
}
//求身高的值
public static void getH (Student[] s){
boolean flag = false;
for(int i =0;i<s.length;i++){
for(int j=0;j<i;j++){
if(s[i].getHeigth()==s[j].getHeigth()){
flag = true;
break;
}
}
if(!flag){
System.out.println(s[i].getHeigth());
}else{
flag = false;
}
}
}
//求最高的身高
public static int getMax(Student[] s){
int max = s[0].getHeigth();
for(int i = 0;i<s.length;i++){
if(s[i].getHeigth()>max){
max = s[i].getHeigth();
}
}
return max;
}
}
2.二维数组
二维数组是,在一维数组的空间内继续存放数组。
2.1二维数组的声明
- 数据类型[][] 数组名;
- 数据类型 数组名[][];
- 数据类型[] 数组名[];
2.2二维数组的初始化
-
动态初始化:
在构建外层数组对象之后,直接构建内层的每一个小数组
数据类型[][] 数组名 = new 数据类型[整数n外层数组长度] [整数m内层每一个小数组长度];
先构建外层数组对象,再构建内层的每一个小数组
数据类型[][] 数组名 = new 数据类型[整数n外层数组长度];
构建内层的每一个小数组 : 就是一维数组的构建方式
-
静态初始化:
创建数组的同时赋值 数据类型[][] 数组名 = new 数据类型[][]{{1,2,3},{4,5},{6}…};
数据类型[][] 数组名 ={{1,2,3},{4,5},{6}…};
public class ArrayDemo07 {
public static void main(String[] args) {
//声明
int[][] arr ;
//动态
arr = new int[3][2];
//赋值
arr[0][0] = 1;
arr[0][1] = 2;
arr[1][0] = 3;
arr[1][1] = 4;
arr[2][0] = 5;
arr[2][1] = 6;
//先构建外层数组对象,再构建内层的每一个小数组
double[][] arr2 = new double[2][];
//构建内层的每一个小数组
arr2[0] = new double[3];
arr2[1] = new double[]{1.1,2.2};
arr2[0][0] = 100;
arr2[0][1] = 200;
arr2[0][2] = 300;
//静态初始化
int[][] arr3 = new int[][]{{1,2,3},{4,5},{6}};
//获取
System.out.println(arr3[0][0]);
System.out.println(arr3[0][1]);
System.out.println(arr3[0][2]);
System.out.println(arr3[1][0]);
System.out.println(arr3[1][1]);
System.out.println(arr3[2][0]);
//简化写法
int[][] arr4 = {{1,2,3},{4,5},{6}};
}
}
2.3二维数组遍历
双重循环嵌套遍历:
public class ArrayDemo08 {
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5},{6}};
//foreach--foreach
for(int[] i:arr){
//i是每一个内层小数组
for(int j:i){
//j是内层小数组中的每一个数据值
System.out.println(j);
}
}
System.out.println("-----------------------------------");
//普通嵌套增强
for(int i=0;i<=arr.length-1;i++){
for(int j:arr[i]){
System.out.println(j);
}
}
}
}
3.可变参数
- 在使用可变参数过程中,形参与实参要一一对应;
- 在jdk1.7之后,提出可变参数的新特性,使用…表示可变参数;
- 可变参数的个数,可以为0~n个,个数不固定,数据类型要求一致,由形参决定;
写法:数据类型…参数名
值得注意的是:在方法的内部,默认为可变参数构建一个数组,存储这些实参,想要使用可变参数的数据,通过数组的使用方式操作,如果方法的参数列表中存在多个参数,可变参数要在参数列表的最后。
public class Test03 {
public static void main(String[] args) {
char[] arr = new char[]{'a','1','b','c'};
test(1,2,3,5,8,11);
test2(arr);
}
public static void test(int ... i){//可变参数默认在方法中构建一个数组存放参数
for (int j:i) {
System.out.println(j);
}
//System.out.println(i);
}
public static void test2(Object ... obj){
System.out.println(" ");
}
}
4.异常
4.1Exception
- CheckedException 检查时异常 | 编译时异常
- RuntimeException 运行时异常
常见的运行时期异常:
- 索引越界 ArrayIndexOutOfBoundsException
- 数学异常 ArithmeticException
- 数据格式异常 NumberFormatException
public class ExceptionDemo01 {
public static void main(String[] args) {
//运行时期异常
String s = null;
if(s!=null){
System.out.println(s.length());
}
int[] arr = new int[2];
//System.out.println(arr[3]);
//System.out.println(5/0);
s = "123abc";
System.out.println(Integer.valueOf(s));;
System.out.println("main方法结束");
//编译时异常
//InputStream is = new FileInputStream("D://hahaha.txt");
}
}
4.2异常处理方案
4.2.1异常抛出
把异常抛出到上一层,谁调用谁解决;
4.2.2异常捕获
try{
有可能出现异常的代码;
}catch(NullPointerException e){
执行对应的代码…
}catch(Exception e){
e…;
//如果出现种异常,执行的代码
}finally{
无论是否出现异常,都会执行finally的代码
}
- 一个try后面可以跟一到多个catch…
- 范围大的catch一定要写在后面
- 如果try中的代码没有出现异常,try中的正常执行完毕
- 如果try中一旦遇到异常,try中后面的代码不会执行,直接执行catch进行判断,从上到下进行判断,找到能够接受当前出现异常对象的catch,直接执行对应的语句体
- 无论是否try中出现异常,无论异常是否能够捕获,都会在结束之前执行finally中的代码
注意:一个异常出现如果不处理,后面程序无法执行;一个异常出现,如果通过异常处理方案进行处理,后面代码可能正常执行。
public class ExceptionDemo02 {
public static void main(String[] args) {
try {
System.out.println("try开始了");
test();
System.out.println(5/0);
System.out.println("try结束了");
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
System.out.println("最后的最后我们都要离开....");
}
System.out.println("main方法结束了");
}
static void test() throws FileNotFoundException {
//编译时异常
InputStream is = new FileInputStream("D://hahaha.txt");
}
}
4.3自定义异常
必须继承自Exception,运行时期异常需要继承自RuntimeException或者其子类。
throw 制造异常
throws 抛出异常