栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java每周一记(3)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java每周一记(3)

目录

1.异常机制

2.自定义异常

3.容器

 泛型

Collection接口   List

Map接口

 

 


(一)异常机制

1.概念

异常指程序运行过程中出现的非正常现象,例如除数为零、需要处理的文件不存在、数 组下标越界等。

异常类:用来描述和处理异常的类。异常类定义中包含了该类异常的信息和对异常进行处理的方法。

Java采用面向对象的方式处理异常,处理过程: 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给 JRE。           捕获异常:JRE 得到该异常后,寻找相应的代码来处理该异常。JRE 在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。

2.分类

根类:java.lang.Throwable     Throwable 下面又派生了两个子类:Error 和 Exception。

Error是程序无法处理的错误,表示运行应用程序中较严重问题。                                                      Exception是程序本身能够处理的异常,Exception类是所有异常类的父类。

Java的异常可分为:RuntimeException( 运行时异常 ),CheckedException (已检查异常)

Runtime Exception解决所修改的代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestRuntimeException {
	public static void main(String[] args) {
		//ArithmeticException 异常:试图除以 0
		int b=0;
		if(b!=0) {
			System.out.println(1/b);
		}
		//NullPointerException 异常
		String str=null;
		if(str!=null)
			System.out.println(str.charAt(0));
		//ClassCastException 异常
		Fruits f=new Apple();
		if(f instanceof Orange) {
			Orange o=(Orange) f;
		}
		//ArrayIndexOutOfBoundsException 异常
		int[] arr=new int[5];
		int a=5;
		if(a

CheckedException异常处理的方式:

1.使用“try/catch”捕获异常

2. 使用“throws”声明异常

 1.try-catch-finally

try语句是正常执行的语句,catch语句是对异常处理的语句,final 不管是否发生了异常都必须要执行,通常在final中关闭已打开的资源。

注意:当异常处理的代码执行结束以后,不会回到 try 语句去执行尚未执行的代码。

 2.throws

当CheckedException产生时,不一定立刻处理它,可以再把异常throws出去。  在方法中使用try-catch-finally是由这个方法来处理异常。但是在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理。

如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开。

注意:方法重写中声明异常原则:子类重写父类方法时,如果父类方法有声明异常,那么子类声明的异常范围不能超过父类声明的范围。

 (二)自定义异常

自定义异常类如果继承 Exception 类,则为 CheckedException 异常,必须对其进行处理;如果不 想处理,可以让自定义异常类继承运行时异常 RuntimeException 类。

public class Test {
	public static void main(String[] args) {
		Person p=new Person();
		p.setAge(-10);
	}

}

class Person{
	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		if(age<0) {
			throw new IllegalAgeException("人的年龄不应该为负数");
		}
		this.age = age;
	}
	
}

class IllegalAgeException extends RuntimeException {
		//默认构造器
		public IllegalAgeException() {
		}
		//带有详细信息的构造器,信息存储在 message 中
		public IllegalAgeException(String message) {
		   super(message);
		}
}
		

 (三)容器

先前学过的数组就是一种容器。

数组的优势:是一种简单的线性序列,可以快速地访问数组元素,效率高。

 数组的劣势:不灵活。容量需要事先定义好,不能随着需求的变化而扩容。

1.泛型

 本质是数据类型的参数化。在类的声明处增加泛型列表 ,(一般采用这三个字母)

public class TestGenerics {
	public static void main(String[] args) {
		MyCollection mc=new MyCollection<>();
		mc.set("aaa", 0);
		mc.set("bbb", 1);
		String str=mc.get(1);
		System.out.println(str);	//加了泛型,直接返回String类型,不用强制转换;
	}

}
class MyCollection{  //  E:表示泛型
	Object[] objs=new Object[5];
	
	public E get(int index) {
		return (E) objs[index];
	}
	public void set(E e,int index) {
		objs[index]=e;
	}
	
}

 容器相关类都定义了泛型,在使用容器类时都要使用泛型(建议使用,不使用也不会报错)

2.College接口   List

Collection接口中的方法:

import java.util.*;

public class TestList {
	public static void main(String[] args) {
		Collection c=new ArrayList<>();
		
		System.out.println(c.size());// int size()容器中元素的数量
		System.out.println(c.isEmpty());//true,容器里没有元素
		//增加元素到容器中
		c.add("小红");
		c.add("小明");
		System.out.println(c);
		System.out.println(c.size());
		System.out.println(c.isEmpty());//false,容器里面有元素
		//容器中是否包含该元素
		System.out.println(c.contains("小明"));
		System.out.println(c.contains("小丽"));
		//转化成Object数组
		Object[] objs=c.toArray();
		System.out.println(objs);
		//从容器中移除元素
		c.remove("小明");
		System.out.println(c);
		//清空容器中所有元素
		c.clear();
		System.out.println(c.size());
	}

}
public static void test2() {
		List list01=new ArrayList<>();
		list01.add("aa");
		list01.add("bb");
		list01.add("cc");
		
		List list02=new ArrayList<>();
		list02.add("aa");
		list02.add("dd");
		list02.add("ee");
		
		System.out.println("list01:"+list01);
		System.out.println(list01.containsAll(list02)); //false list01是否包含list02中所有元素
		list01.addAll(list02);//将list02中所有元素增加到本容器
		System.out.println("list01:"+list01);
		list01.removeAll(list02);//移除list01和list02中都包含的元素
		System.out.println("list01:"+list01);
		list01.retainAll(list02);//移除俩容器中非交集的元素
		System.out.println("list01:"+list01);
	}

list01:[aa, bb, cc]
false
list01:[aa, bb, cc, aa, dd, ee]
list01:[bb, cc]
list01:[]
 

 List是有序、可重复的容器。

List中操作索引方法:

 public static void test3() {
    	List list=new ArrayList<>();
    	list.add("A");
    	list.add("B");
    	list.add("C");
    	list.add("D");
    	System.out.println(list);//[A,B,C,D]
    	list.add(2,"高");
    	System.out.println(list);//[A,B,高,C,D]
    	list.remove(2);
    	System.out.println(list);//[A,B,C,D]
    	list.set(2, "c");
    	System.out.println(list);//[A,B,c,D]
    	System.out.println(list.get(1));//返回:B
    	list.add("B");
    	System.out.println(list);//{A,B,c,D,B]
    	System.out.println(list.indexOf("B"));//1 从头到尾找到第一个"B"
    	System.out.println(list.lastIndexOf("B"));//4 从尾到头找到第一个"B"
    }

 List接口常用的实现类有3个:ArrayList、LinkedList和Vector。

 ArrayList底层是用数组实现的存储。 特点:查询效率高,增删效率低,线程不安全.(一般使用它)

LinkedList底层用双向链表实现的存储。特点:查询效率低,增删效率高,线程不安全。

需要线程安全时,用Vector。 

3.Map接口

 Map就是用来存储“键(key)-值(value) 对”的。Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复。

Map 接口的实现类有HashMap、TreeMap、HashTable、Properties等。

常用方法:

import java.util.HashMap;
import java.util.Map;

public class TestMap {
	public static void main(String[] args) {
		Map m1 = new HashMap<>();
		Map m2 = new HashMap<>();

		m1.put(1, "one");
		m1.put(2, "two");
		m1.put(3, "three");
		m2.put(1, "一");
		m2.put(2, "二");
		System.out.println(m1.size());
		System.out.println(m1.containsKey(1));//容器中是否包含键对象对应的键值对
		System.out.println(m2.containsValue("two"));//容器中是否包含值对象对应的键值对
		//map中的键不能重复!!如果重复(是否重复是根据equals方法来判断),则新的覆盖旧的。
	    m1.put(3, "third");
	    Map m3 = new HashMap<>();
	    m3.putAll(m1);//将m1的所有键值对存放到本map对象
	    m3.putAll(m2);
	    System.out.println("m1:"+m1);
	    System.out.println("m2:"+m2);
	    System.out.println("m3:"+m3);
	}

}

HashMap: 线程不安全,效率高。允许key或value为null。HashMap底层实现采用了哈希表(数据结构)。

  数据结构中由数组和链表来实现对数据的存储,他们各有特点。

      (1) 数组:占用空间连续。 寻址容易,查询速度快。但是,增加和删除效率非常低。

      (2) 链表:占用空间不连续。 寻址困难,查询速度慢。但是,增加和删除效率非常高。

 HashTable: 线程安全,效率低。不允许key或value为null。

存储数据过程:

 

  hash值 = hashcode/hashcode;(简单低下的算法)

相除取余算法:hash值 = hashcode%数组长度(简单常用的方法)                                                  改进后:hash值 = hashcode&(数组长度-1)。

当添加一个元素(key-value)时,首先计算key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,就形成了链表,同一个链表上的Hash值是相同的,所以说数组存放的是链表。 JDK8中,当链表长度大于8时,链表就转换为红黑树,这样又大大提高了查找的效率。

取数据过程:

获得key的hashcode,通过hash()散列算法得到hash值,进而定位到数组的位置。在链表上挨个比较key对象。 调用equals()方法,将key对象和链表上所有节点的key对象进行比较,直到碰到返回true的节点对象为止。返回equals()为true的节点对象的value对象。

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/925002.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号