异常
Java程序运行过程中所发生的异常事件可分为两类:
数组越界异常Exception
空指针异常
除数
StackOverFlower:栈溢出 OutOfMemoryError:内存溢出
Java异常类层次
Java提供的是异常处理的抓抛模型。
•getMessage( ) 方法,用来得到有关异常事件的信息
•printStackTrace( )用来跟踪异常事件发生时执行堆栈的内容。
§程序员通常只能处理Exception,而对Error无能为力。
异常处理是通过try-catch-finally语句实现的。
try catch防止程序可能出现的异常,在捕获异常的代码块中,如果前面有异常就不会执行后面的
try
{
...... //可能产生异常的代码
}
catch( ExceptionName1 e )
{
...... //当产生ExceptionName1型异常时的处置措施
}
catch( ExceptionName2 e )
{
...... //当产生ExceptionName2型异常时的处置措施
}
[ finally{
...... //无条件执行的语句,可写可不写,一定会执行
} ]
抛出异常 throws
§声明抛出异常是Java中处理异常的第二种方式
可以main方法抛出异常,直接抛到java虚拟机了,程序中就不能处理
子类重写父类,子类不能抛出比父类更大的异常
用户自定义异常类
class MyException extends Exception {
private int idnumber;
public MyException(String message, int id) {
super(message);
this.idnumber = id;
}
public int getId() {
return idnumber;
}
}
public class Test01{
public void regist(int num) throws MyException {
if (num < 0)
throw new MyException("人数为负值,不合理",3);
else
System.out.println("登记人数" + num );
}
public void manager() {
try {
regist(100);
} catch (MyException e) {
System.out.print("登记失败,出错种类"+e.getId());
}
System.out.print("本次登记操作结束");
}
public static void main(String args[]){
Test8_6 t = new Test8_6();
t.manager();
}
}
集合
Java集合类存放于 java.util 包中,是一个用来存放对象的容器。
Java 集合可分为 Set、List 和 Map 三种大体系
Set:无序、不可重复的集合
List:有序,可重复的集合
Map:具有映射关系的集合
在 JDK5 之后,增加了泛型,Java 集合可以记住容器中对象的数据类型
HashSet
HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。我们大多数时候说的set集合指的都是HashSet
HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。
HashSet 具有以下特点:
不能保证元素的排列顺序
不可重复
HashSet 不是线程安全的
集合元素可以使 null
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。
Set set=new HashSet();
// Set<Object> set=new HashSet<Object>();//Object与上面的等价
set.add("aa");//添加
set.add(1);
System.out.println(set);
set.remove(1);//移除
System.out.println(set);
System.out.println(set.contains(1));//判断是否包含
set.clear();//清空
System.out.println(set);
//使用遍历器
set.add("q");
set.add("qw");
set.add("qwe");
set.add("qwe");//set集合不存重复值
set.add(null);
set.add(true);
Iterator iterator=set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//for each 迭代集合 推荐使用
for (Object obj:set) {//把set每个值取出来赋值给obj,直到循环完成
System.out.println(obj);
}
System.out.println(set.size());//获取集合的元素个数
//如果想要集合存同样类型的集合,用泛型
Set<String> stringSet=new HashSet<String>();//指定String集合的泛型,不能用其他的
stringSet.add("sss");
TreeSet
TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。
TreeSet 支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。
自然排序
TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序排列
//TreeSet自然排序
Set<Integer> set = new TreeSet<Integer>();
set.add(5);
set.add(2);
set.add(1);
set.add(3);
set.add(6);
System.out.println(set);//运行结果:[1, 2, 3, 5]
set.remove(5);
set.contains(2);
// set.clear();
Iterator<Integer> iterator=set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//for each 迭代集合 推荐使用
for (Object obj:set) {//把set每个值取出来赋值给obj,直到循环完成
System.out.println(obj);
}
System.out.println(set.size());//获取集合的元素个数
//如果想要集合存同样类型的集合,用泛型
Set<String> stringSet=new TreeSet<String>();//指定String集合的泛型,不能用其他的
stringSet.add("sss");
System.out.println(stringSet);
定制排序
如果需要实现定制排序,则需要在创建 TreeSet 集合对象时,提供一个 Comparator 接口的实现类对象。由该 Comparator 对象负责集合元素的排序逻辑
public class Test2 {
public static void main(String[] args) {
Person p1=new Person("张三",20);
Person p2=new Person("李四",16);
Person p3=new Person("王五",29);
Person p4=new Person("刘麻子",23);
Set<Person> setp=new TreeSet<Person>(new Person());
setp.add(p1);
setp.add(p2);
setp.add(p3);
setp.add(p4);
for (Person p:setp) {
System.out.println(p.name+" "+p.age);
}
}
}
class Person implements Comparator<Person> {//把对象存在TreeSet中,按照年龄排序
int age;
String name;
public Person(){
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
//正序排序 李四 16
//张三 20
//刘麻子 23
//王五 29
// public int compare(Person o1, Person o2) {//年龄正序排序
// if (o1.age>o2.age){
// return 1;
// }else if ((o1.age<o2.age)){
// return -1;
// }else {
// return 0;
// }
// }
public int compare(Person o1, Person o2) {//年龄倒叙序排序
if (o1.age>o2.age){
return -1;
}else if ((o1.age<o2.age)){
return 1;
}else {
return 0;
}
}
}
List与ArrayList
List 代表一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引
List 允许使用重复元素,可以通过索引来访问指定位置的集合元素。
List 默认按元素的添加顺序设置元素的索引。
List 集合里添加了一些根据索引来操作集合元素的方法
List<String> list = new ArrayList<String>();
list.add("b");//第一个,索引下标0
list.add("d");//索引下标1
list.add("c");//索引下标2
list.add("a");//索引下标3
list.add("d");//允许使用重复元素
System.out.println(list);
System.out.println(list.get(2));//通过索引来访问指定位置的集合元素
list.add(1,"f");//在指定索引下标的位置插入数据
System.out.println(list);
List<String> l = new ArrayList<String>();
l.add("123");
l.add("456");
list.addAll(2, l);//在指定索引下标的位置插入集合
System.out.println(list);
System.out.println(list.indexOf("d"));//获取指定元素在集合中第一次出现的索引下标
System.out.println(list.lastIndexOf("d"));//获取指定元素在集合中最后一次出现的索引下标
list.remove(2);//根据指定的索引下标移除元素
System.out.println(list);
list.set(1, "ff");//根据指定的索引下标修改元素
System.out.println(list);
//根据索引下标的起始位置截取一段元素形参一个新的集合,截取的时候,包含开始的索引不包含结束时的索引
List<String> sublist = list.subList(2, 4);//取索引下标在大于等于2小于4的元素
System.out.println(sublist);
System.out.println(list.size());//集合的长度
ArrayList 和 Vector
Map
Map 用于保存具有映射关系的数据,因此 Map 集合里保存着两组值,一组值用于保存 Map 里的 Key,另外一组用于保存 Map 里的 Value
Map 中的 key 和 value 都可以是任何引用类型的数据
Map 中的 Key 不允许重复,即同一个 Map 对象的任何两个 Key 通过 equals 方法比较中返回 false
Key 和 Value 之间存在单向一对一关系,即通过指定的 Key 总能找到唯一的,确定的 Value。
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("b", 1);//添加数据
map.put("c", 2);
map.put("e", 2);
System.out.println(map);
System.out.println(map.get("b"));//根据key取值
map.remove("c");//根据key移除键值对
System.out.println(map);
System.out.println(map.size());//map集合的长度
System.out.println(map.containsKey("a"));//判断当前的map集合是否包含指定的key
System.out.println(map.containsValue(10));//判断当前的map集合是否包含指定的value
// map.clear();//清空集合
Set<String> keys = map.keySet();//获取map集合的key的集合
map.values();//获取集合的所有value值
//遍历map集合,通过map.keySet();
for(String key : keys){
System.out.println("key: " + key + ", value: " + map.get(key));
}
//通过map.entrySet();遍历map集合
Set<Map.Entry<String, Integer>> entrys = map.entrySet();
for(Map.Entry<String, Integer> en : entrys){
System.out.println("key: " + en.getKey() + ", value: " + en.getValue());
}
HashMap & Hashtable
HashMap 和 Hashtable 是 Map 接口的两个典型实现类
区别:
与 HashSet 集合不能保证元素的顺序一样,Hashtable 、HashMap 也不能保证其中 key-value 对的顺序
Hashtable 、HashMap 判断两个 Key 相等的标准是:两个 Key 通过 equals 方法返回 true,hashCode 值也相等。
Hashtable 、相等的标准是:两个 Value 通过 equalHashMap 判断两个 Values 方法返回 true
TreeMap
TreeMap 存储 Key-Value 对时,需要根据 Key 对 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。
TreeMap 的 Key 的排序:
//TreeMap的自然排序是字典排序
Map<Integer,String> map = new TreeMap<Integer, String>();
map.put(4, "a");
map.put(2, "a");
map.put(3, "a");
map.put(1, "a");
System.out.println(map);
Map<String,String> map1 = new TreeMap<String, String>();
map1.put("b", "b");
map1.put("c", "c");
map1.put("d", "d");
map1.put("a", "a");
map1.put("ab", "ab");
map1.put("1", "ab");
map1.put("10", "ab");
System.out.println(map1);
结果
{1=a, 2=a, 3=a, 4=a}
{1=ab, 10=ab, a=a, ab=ab, b=b, c=c, d=d}
操作集合的工具类:Collections
Collections 中提供了大量方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法
排序操作:
reverse(List):反转 List 中元素的顺序
shuffle(List):对 List 集合元素进行随机排序
sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
查找、替换
Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object):返回指定集合中指定元素的出现次数
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
List<String> list = new ArrayList<String>();
list.add("b");
list.add("cd");
list.add("ca");
list.add("a");
list.add("a");
list.add("1");
System.out.println(list);
Collections.reverse(list);//反转 List 中元素的顺序
System.out.println(list);
Collections.shuffle(list);//对 List 集合元素进行随机排序
System.out.println(list);
//
Collections.sort(list);//list集合字典升序排序
System.out.println(list);
System.out.println(Collections.frequency(list, "x"));//返回指定集合中指定元素的出现次数
Collections.replaceAll(list, "b", "bb");//使用新值替换 List 对象的所有旧值
System.out.println(list);
// Collections.swap(list, 0, 4);//将指定 list 集合中的 i 处元素和 j 处元素进行交换
// System.out.println(list);
// System.out.println(Collections.max(list));
// System.out.println(Collections.min(list));
//
// Student s1 = new Student(14,"张三");
// Student s2 = new Student(12,"李四");
// Student s3 = new Student(13,"王五");
// Student s4 = new Student(11,"小六");
//
// List<Student> stus = new ArrayList<Student>();
// stus.add(s1);
// stus.add(s2);
// stus.add(s3);
// stus.add(s4);
//
// Student s = Collections.max(stus, new Student());
// System.out.println(s.name + "," + s.age);
//
// Student ss = Collections.min(stus, new Student());
// System.out.println(ss.name + "," + ss.age);
// for(Student stu : stus){
// System.out.println(stu.name + "," + stu.age);
// }
//
// Collections.sort(stus, new Student());
// System.out.println("-----------------------------");
// for(Student stu : stus){
// System.out.println(stu.name + "," + stu.age);
// }
}
}
class Student implements Comparator<Student>{
int age;
String name;
public Student(){
}
public Student(int age,String name){
this.age = age;
this.name = name;
}
@Override
public int compare(Student o1, Student o2) {//根据年龄升序排列对象
if(o1.age > o2.age){
return 1;
}else if(o1.age < o2.age){
return -1;
}else{
return 0;
}
同步控制
Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题
Java泛型
解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可
•Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。
泛型类
泛型接口
泛型方法
无返回值,有返回值,形参是可变参数的泛型方法
class Cc<E>{
private E e;
/**
* 静态方法的泛型方法
* @param t
*/
public static <T> void test3(T t){
//在静态方法中,不能使用类定义泛型,如果要使用泛型,只能使用静态方法自己定义的泛型
// System.out.println(this.e);
System.out.println(t);
}
/**
* 无返回值的泛型方法
* @param s
*/
public <T> void test(T s){
//在类上定义的泛型,可以在普通的方法中使用
System.out.println(this.e);
T t = s;
}
/**
* 有返回值的泛型方法
* @param s
*/
public <T> T test1(T s){
return s;
}
/**
* 形参为可变参数的泛型方法
* @param strs
*/
public <T> void test2(T... strs){
for(T s : strs){
System.out.println(s);
}
}
}
测试
Cc<Object> c = new Cc<Object>();
c.test("xxx");
//泛型方法,在调用之前没有固定的数据类型
//在调用时,传入的参数是什么类型,就会把泛型改成什么类型
//也就是说,泛型方法会在调用时确定泛型距离数据类型
Integer i = c.test1(2);//传递的参数是Integer,泛型就固定成Integer,返回值就是Integer
Boolean b = c.test1(true);//传递的参数是Boolean,泛型就固定成Boolean,返回值就是Boolean
通配符
有限制的通配符
举例:
•<? extends Person> (无穷小 , Person]
只允许泛型为Person及Person子类的引用调用
•<? super Person > [Person , 无穷大)
只允许泛型为Person及Person父类的引用调用
•<? extends Comparable>
只允许泛型为实 现Comparable接口的实现类的引用调用
import java.util.ArrayList;
import java.util.List;
public class Test2 {
public static void main(String[] args) {
Dd d = new Dd();
List<String> l1 = new ArrayList<String>();
d.test(l1);
List<Integer> l2 = new ArrayList<Integer>();
d.test(l2);
List<C1> lc = new ArrayList<C1>();
d.test1(lc);
List<D1> ld = new ArrayList<D1>();
d.test1(ld);
// List<B3> lb = new ArrayList<B3>();
// d.test1(lb);
d.test2(lc);
List<A1> la = new ArrayList<A1>();
d.test2(la);
// d.test2(ld);
List<IAImpl> lia = new ArrayList<IAImpl>();
d.test3(lia);
// d.test3(la);
}
}
class Dd{
public void test(List<?> list){//test方法需要一个list集合的参数,不确定list集合到底是存的数的类型是什么
}
public void test1(List<? extends C1> list){//list参数的元素数据类型是C1及其子类
}
public void test2(List<? super C1> list){//list参数的元素数据类型是C1及其父类
}
public void test3(List<? extends IA> list){//list参数的元素数据类型是IA的实现类
}
}
class A1{}
class B3 extends A1{}
class C1 extends B3{}
class D1 extends C1{}
interface IA{}
class IAImpl implements IA{}
enum 定义枚举类
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;
public class Test4 {
public static void main(String[] args) {
new TestB().test1();
@SuppressWarnings({ "rawtypes", "unused" })
List list = new ArrayList();
}
}
class TestA{
// @TestAnn()
public void test(){
}
}
class TestB extends TestA{
@TestAnn(id=100,desc="姓名")
String name;
@Override
public void test() {
// TODO Auto-generated method stub
super.test();
}
@Deprecated
public void test1(){
}
}
@Target(ElementType.FIELD)//这个注解类是给其他类的属性做注解
@Retention(RetentionPolicy.RUNTIME)//定义注解的声明周期
@Documented
@interface TestAnn{
public int id() default 0;
public String desc() default "";
}