一、数组
数组的概念
概念:具有一组相同数据类型的数据结构。(理解为容器,就是装数据的)
相同数据类型
数据结构:在内存中是连续的内存空间。
数组的使用
使用:
step1:创建数组
step2:操作数据:存储数据,获取数据
数组中可以存储任意类型的数据,但是数组本身是引用类型的。
语法:
动态创建数组:创建和赋值分开写。
数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度];
1
数组定义格式详解:
数组存储的数据类型: 创建的数组容器可以存储什么数据类型。
[] : 表示数组。
数组名字:为定义的数组起个变量名,满足标识符规范,可以使用名字操作数组。
new :关键字,创建数组使用的关键字。
数组存储的数据类型: 创建的数组容器可以存储什么数据类型。
[ 长度]:数组的长度,表示数组容器中可以存储多少个元素。
注意:创建数组时要指明数组的大小(长度,容量),然后再使用,数组有定长特性,长度一旦指定,不可更改。
int [] arr = new int[5]; //先创建 arr[0] = 1; arr[1] = 2; arr[2] = 3;
静态创建数组:创建数组和赋值写一起
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...}; 数据类型[] 数组名 = {元素1,元素2,元素3...};
int[] arr = {1,2,3,4,5}
示例:
package com.tuling.part1; public class Demo1 { public static void main(String[] args) { int i = 100; /* 数组的标识是[];arr=Array 语法: 数据类型[] 数组名 = new 数据类型[数组的长度]; 数组是引用类型 数组声明之后,没有赋值,那么他的默认值和成员变量一样。。。 */ //第一种定义方式:动态初始化, int[] arr = new int[3]; //System.out.println(arr); //方法数组元素的语法:数组名[下标] arr[0] =1;//存数据 arr[1] =2; arr[2]= 5; System.out.println(arr[0]);//取数据 System.out.println("arr[1]--->"+arr[1]); System.out.println("arr[2]---->"+arr[2]); //System.out.println("arr[2]---->"+arr[3]);//访问数组的元素的时候,下标超过了边界,那么会报异常 //java.lang.ArrayIndexOutOfBoundsException: 3,这个叫数组越界异常 // String[] arr2 = new String[3]; // System.out.println("arr2[0]---->"+arr2[0]); //可以新建任意类型的数组,但是数组本身是引用类型 //Object[] arr2 = new Object[3]; //第二种:静态初始化 /* 左边是声明数组,开辟内存; 右边里面大括号{}包含的元素个数,顺序,会自动计算长度,还有元素的位置 */ int[] arr2 = {1,4,5,6,7};// //访问数组的长度:数组名.length System.out.println("arr2.length="+arr2.length); } }
数组名(arrName),数组的类型(type),长度(容量length),下标(index),元素(element)
注意点:
数组只有一个名称,即标识符
元素索引标明了元素在数组中的位置,下标从0开始
数组中的每个元素都可以通过下标来访问
数组的长度固定不变,避免数组越界
数组变量属于引用类型
数组元素的默认值和成员变量的默认值一样
数组的遍历
方法一
普通for循环:
for(int i =0 ;i < arr.length;i++){ System.out.println(arr[i]); }
方法二
增强for循环(jdk1.5):
//语法: for(type element : array){ System.out.println(element); } //示例代码: for (int e : arr) { System.out.println("--->" + e); }
缺陷:遍历数组或集合时无法访问索引(下标)值
用途:一般用于遍历显示数组或集合中元素的内容。
增强for能不能给数组赋值?
int[] arr = {1,3,4}; int[] arr2= new int[3]; int i=0; for(int e:arr){ //e = 10;//不可以; arr2[i] = e; i++; } for(int a:arr2){ System.out.println(a); }
示例:
package com.tuling.part2; public class Demo2 { public static void main(String[] args) { int[] arr = {1,5,4,3,46};//定义一个数组 System.out.println("数组的长度:"+arr.length); System.out.println("访问数组的元素arr[0]:"+arr[0]); //第一种方式:for循环,通过下标。。。 for(int i=0;i<arr.length;i++){ //i=0;arr[0],访问第一个元素 //i=1;arr[1],访问第二个元素 //... //i=arr.length-1;访问最后一个元素 System.out.print(arr[i]+"\t"); } System.out.println(); System.out.println("-----------------"); //第二种方式:增强for循环,不再通过下标遍历 /* //语法: for(type element : array){ System.out.println(element); } */ for(int e:arr){//把数组arr里面的元素依次赋值给e, System.out.print(e+"\t"); } System.out.println(); System.out.println("----------------"); //增强for给数组元素直接赋值 int[] arr2 = new int[3]; for(int e:arr2){ e = 10;//不可以给数组的元素赋值 } for(int e:arr2){//把数组arr里面的元素依次赋值给e, System.out.print(e+"\t"); } } }
可变参数
一个方法中,参数的类型确定,但是数量不确定。就可以使用可变参数。
方法当中可变参数,就是数组。
语法: 参数类型 … 参数名
调用:参数的数量:0-多个
/** * 求多个整数的和:数量不确定,类型确定 * 可变参数: * 语法:数据类型 ... 参数名 * * @return */ public int getSum(int... nums) { int sum = 0; for(int i= 0;i<nums.length;i++){ sum += nums[i]; } return sum; }
注意事项:
1.一个方法最多只能有一个可变参数。
2.如果形参列表中,除了可变参数,还有其他的参数,可变参数要位于参数列表的末尾。
数组拷贝
浅拷贝:拷贝的是内存地址,
深拷贝:拷贝的是数值。
package com.tuling.part2;
public class Demo2 { public static void main(String[] args) { int[] nums = new int[3]; nums[0] = 1; nums[1] = 4; nums[2] =5; for(int i=0;i<nums.length;i++){ System.out.println("nums["+i+"]---->"+nums[i]); } System.out.println(); int[] arr = nums;//拷贝的是内存地址, arr[0] = 20; System.out.println(arr[0]); System.out.println(nums[0]); int[] arr2 = new int[3]; for(int i=0;i<nums.length;i++){ arr2[i] = nums[i];//拷贝的是数值。 } arr2[0] = 90; System.out.println("arr2[0]--->"+arr2[0]); System.out.println("nums[0]--->"+nums[0]); } }
Arrays数组的工具类
常用方法:
binarySearch(数组,key)–>int,二分搜索
sort(数组)–>void,排序
toString(数组)–>String,按照字符串打印数组中的内容
copyOf(原始数组,新数组长度)–>新数组,数组拷贝
equals(数组1,数组2)–>boolean
示例:
int[] arr1 = {1,3,4,5,8,3}; int key = 5; System.out.println("5所在的下标:"+Arrays.binarySearch(arr1,key)); //Arrays.copyOf,从arr1数组中找打4个元素给新的数组 int[] arr2 = Arrays.copyOf(arr1,15);//深拷贝 System.out.println("遍历新的数组:"); for(int e:arr2){ System.out.print(e+"\t"); } System.out.println(); arr2[0] = 100; System.out.println("arr1[0]--->"+arr1[0]); System.out.println("arr2[0]--->"+arr2[0]); System.out.println("-------------"); int[] arr3 = {1,3,4,5}; int[] arr4 = {1,3,4,5}; System.out.println("两个数组是否相等:"+arr3.equals(arr4)); System.out.println("两个数组是否相等:"+Arrays.equals(arr3,arr4)); System.out.println("---------"); System.out.println(Arrays.toString(arr4)); System.out.println("---------"); boolean[] arr5 = new boolean[5]; Arrays.fill(arr5,false); System.out.println("打印一下:"); System.out.println(Arrays.toString(arr5)); // for(int i=0;i<arr5.length;i++){ // arr5[i] = true; // } System.out.println("------------"); int[] arr6 = {4,43,6,4,7}; Arrays.sort(arr6); System.out.println(Arrays.toString(arr6));
二维数组
一维数组,容器,存储了一组数据。数组名配合下标获取到的就是元素数据了,也就是数值。
二维数组,容器,存储一维的一维。二维数组中的元素,而是一维数组。
package com.tuling.part4;
public class Demo4 { public static void main(String[] args) { int[] arr = {1,3,5,6,6}; int[][] arr2 = new int[3][4]; System.out.println("arr2:"+arr2);//二维数组的地址 System.out.println("arr2.length:"+arr2.length);//二维数组的长度 System.out.println("arr2[0]:"+arr2[0]);//第一个一维数组的地址 System.out.println("arr2[0].length:"+arr2[0].length);//第一个一维数组的长度 System.out.println("arr2[0][0]:"+arr2[0][0]);//第一个一维数组的第一个元素; System.out.println("--------------------------"); //二维的数组的静态声明 int[][] arr3 = {{1,2,3},{4,5},{6,7}}; System.out.println("二维数组的打印:"); for(int i=0;i<arr3.length;i++){//外层控制二维里面有多少个一维 for(int j=0;j<arr3[i].length;j++){ System.out.print(arr3[i][j]+"\t"); } System.out.println(); } System.out.println("--------------"); int[][] arr4 = new int[3][]; System.out.println(arr4[0]); arr4[0] = new int[3]; arr4[1] = new int[2]; arr4[2] = new int[4]; } }
二、异常
概念
程序在运行时的时候,发生的不正常事件,就是所谓的异常。
异常分类
Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中。
Error:JVM、硬件、执行逻辑错误,不能手动处理。 常见错误: StackOverflowError、 OutOfMemoryError等。
Exception:程序在运行和配置中产生的问题,可处理。
RuntimeException:运行时异常,可处理,可不处理。
CheckedException:检查时异常,必须处理
package com.tuling.part5; /** * 异常和错误的区别: */ public class Demo { public static void main(String[] args) { //int[] arr = new int[3]; //System.out.println(arr[0]); //数组越界异常,可以处理 //System.out.println(arr[3]);//java.lang.ArrayIndexOutOfBoundsException: 3 //错误: int[] arr2 = new int[1024*1024*1024]; } }
检查异常:由编译器能够检查出来的异常。外部原因导致的异常,程序中必须处理。
FileNotFoundExcetpion
IOException
SQLException
运行时异常:RuntimeException,也叫非受检异常,编译器不检查的异常。往往一些代码的逻辑问题。
NullPointerException
ArrayIndexOutOfBoundsException//数组越界
ArithemicException
ClassCastException
NumberFormatException
示例:
package com.tuling.part5; import java.io.File; import java.io.FileInputStream; import java.text.SimpleDateFormat; import java.util.Date; public class Demo5 { public static void main(String[] args) { int i=10; int j = 0; try{ //int div =i/j;//运行时异常,运行的过程中抛出的异常, //可能抛出异常的代码 //System.out.println("div:"+div); int k = Integer.parseInt("wowo"); }catch (ArithmeticException e){ //异常的处理 //System.out.println(); e.printStackTrace(); }catch (NumberFormatException e){ e.printStackTrace(); } System.out.println("end..........."); //SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd"); //sdf.parse("wowowwo");//检查异常 // File file = new File("c:\\a.jpg"); // FileInputStream fis = new FileInputStream(file); } }
异常产生和传递
异常产生
自动抛出异常:当程序在运行时遇到不符合规范的代码或结果时,会产生异常。
手动抛出异常:语法:throw new 异常类型(“实际参数”)。
产生异常结果:相当于遇到 return语句,导致程序因异常而终止。
异常传递
异常的传递:
按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)。
受查异常:throws 声明异常,修饰在方法参数列表后端。
运行时异常:因可处理可不处理,无需声明异常。
异常的处理
捕获异常:try,catch,finally
语法规则:
try{ //可能产生异常的代码 }catch(异常类型1 e){ //捕获异常的处理 }catch(异常类型2 e){ //捕获异常的处理 }finally{ //无论程序是否产生异常,此处的代码一定会被执行。 //比如说:释放资源,删除临时文件等。。。 }
注意点:
1.一个try可以匹配多个catch语句
2.如果try中产生了异常对象,那么会跳出try,进到相应的catch中处理异常,从上向下匹配。
3.如果是多个catch语句,那么小的异常捕获处理写前面,大的异常捕获处理写后面。
4.finally是可选的
快捷键
ctrl+alt+t:try,catch,finally语句块
ctrl+alt+L:格式化代码
声明异常throws 方法级别上,向外抛出异常。 方法的声明上就要通过throws关键字声明抛出异常: public static void test1(int i,int j)throws NullPointerException{ } [修饰符1,修饰符2.。。] 返回值类型/void 方法名(参数列表) 异常的声明{ }
按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)。
public static void test1() throws ArithmeticException{ int i=10; int j =0; int div = i/j; System.out.println("div:"+div); System.out.println("test1.....end....."); } public static void test2() throws ArithmeticException{ // try { // test1(); // } catch (ArithmeticException e) { // e.printStackTrace(); // } test1(); System.out.println("test2......end...."); } public static void test3() throws FileNotFoundException { File file = new File("c:\\a.jpg"); FileInputStream fis = new FileInputStream(file); } public static void test4() throws Exception{ //FileNotFoundException test3();//检查异常一定要处理,强制处理 } public static void test5() throws Exception{ } public static void test6(){ test5(); } public static void main(String[] args) { try { test2(); } catch (ArithmeticException e) { e.printStackTrace(); } System.out.println("main......end......"); }
运行时异常的抛出,不一定要处理
检查异常的抛出,必须处理
Exception和RuntimeException的区别?
1.RuntimeException是Exception的子类。
2.Exception包含了受检异常,所以抛出Exception以及受检异常时,代码中一定要给与处理。如果抛出的是RuntimeException(运行时异常,非受检)以及它的子类异常,程序中不一定非要处理。
3.重写的时候,子类不能抛出比父类更大的异常
class Person{ public void eat() throws FileNotFoundException{ } } class Student extends Person{ @Override public void eat() throws Exception{ } } public class Demo7 { public void test(Person p){ p.eat(); } public static void main(String[] args) { } }
throw关键字
throw和throws的区别?
1.throws,用于定义方法的时候,声明该方法向外抛出异常。
2.throw,主动抛出一个异常的对象。打断程序的执行。配合trycatch,或者throws来使用。
Exception exception = new Exception("我自定义的异常。。");
try { throw exception;//自己主动抛出的异常 } catch (Exception e) { e.printStackTrace(); } System.out.println("main......end.....");
自定义异常
需继承Exception或Exception的子类,代表特定问题。
异常类型名称望文生义,可在发生特定问题时抛出对应的异常。
常用构造方法:
无参数构造方法。
String message参数的构造方法。
public class AgeException extends RuntimeException{ public AgeException() { super(); // TODO Auto-generated constructor stub } public AgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); // TODO Auto-generated constructor stub } public AgeException(String message, Throwable cause) { super(message, cause); // TODO Auto-generated constructor stub } public AgeException(String message) { super(message); // TODO Auto-generated constructor stub } public AgeException(Throwable cause) { super(cause); // TODO Auto-generated constructor stub } }