异常:
- try catch方法处理异常:
异常类名从控制台上寻找:
由帮助文档可得,此异常为运行时异常
而这类异常则是编译型异常:
- 两种异常
1.运行时异常也可以用try catch处理,也可以不用
2.编译异常指可能会出问题,但不一定要出问题,所以电脑会提醒改动,否则无法正常编译i。
package 实验;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class java {
public static void main(String[] args) {
System.out.println("开始");
method1();
System.out.println("结束");
method2();
}
//编译时异常
public static void method2(){
try{
String s="2048-08-09";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date d=sdf.parse(s);
System.out.println(d);
}catch(ParseException e){
e.printStackTrace();
}
}
//运行时异常
public static void method1() {
try {
int[] arr = {1, 2, 3};
System.out.print(arr[3]);
} catch (ArrayIndexOutOfBoundsException e) {//相当于new一个异常类的对象
System.out.println("不存在此元素");
e.printStackTrace();//在控制台输出异常原因
System.out.println(e.getMessage());//返回throwable的详细消息字符串
System.out.println(e.toString());//更加详细的描述
}
}
}
- throws处理异常:
在运行时异常时无太大意义
public static void main(String[] args) {
System.out.println("开始");
method1();
System.out.println("结束");
System.out.println("开始");
try{
method2();
}catch(ParseException e){
e.printStackTrace();
}
System.out.println("结束");
}
//编译时异常
public static void method2() throws ParseException {
String s="2048-08-09";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date d=sdf.parse(s);
System.out.println(d);
}
在编译型异常中,throw可以认为 是将异常抛出,即暂时不进行处理(但是还是没有处理异常,在主函数中还是需要用try catch进行处理,即谁来调用谁处理)
- 自定义异常
Exception即为异常类的父类
依次选中nnn和super按ctrl+b跟进,可得最后将message传给了detailMessage
创建自己的异常类对象
package 实验;
public class nnn extends Exception {
public nnn(){
}
public nnn(String message){
super(message);
}
}
先要throw一个对象(nnn),然后再throws出去
package 实验;
public class java {
public void check(int score) throws nnn{
if(score<0||score>100){
throw new nnn(“你给的分钟数有误”);
}else{
System.out.println("分数正常");
}
}
}
由于check所在的类中,抛出nnn异常对象,而这个异常继承于Extend,所以是一个编译时异常,所以check就需要用try catch来处理。
package 实验;
import java.util.Scanner;
public class text {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入成绩:");
int i= sc.nextInt();
java a=new java();
try {
a.check(i);
} catch (nnn e) {
e.printStackTrace();
}
}
}
二者区别:
一旦走了throw这一步就一定会有异常,因为new了一个异常对象,但是如果没有这一步的话就不一定有异常。
集合体系结构:
Collection是集合的顶层接口,不能被实例化
- Collection常用方法
- Collection集合的遍历:
package 实验;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class collection {
public static void main(String[] args) {
Collection<String> e=new ArrayList<String>();
e.add("hello");
e.add("world");
e.add("java");
Iterator<String> it =e.iterator();//得到迭代器对象it
sout("it.next");//迭代器方法
sout("it.next");
sout("it.next");
}
}
e.iterator方法的原码如下,相当于多态
hasNext方法:判断有无后继元素
package 实验;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class collection {
public static void main(String[] args) {
Collection<String> e=new ArrayList<String>();
e.add("hello");
e.add("world");
e.add("java");
Iterator<String> it =e.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
- list集合:
- list特有的方法:
(Arraylist有但是Collection中没有)
( size() 用来求集合大小; length用来求数组大小; length()用来求字符串大小)
- 并发修改异常:
报错
成功输出:
简而言之:迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
更准确的解释 - 列表迭代器
列表迭代器和特有方法:
正向遍历:
逆向遍历:
add方法:
注意:这里是通过列表迭代器来添加的,而上面的并发修改异常时通过list集合来添加的。
(输出的是hello world javaee java,是在world后添加,而不是在集合的最后添加)
- 增强for循环:
执行下列代码后,控制台抛出了并发修改异常,说明增强for的内部就是一个Iterator修改器
- 遍历集合的三种方式:
只是为了遍历的话,就用增强for,最方便
若需要索引的话就是用增强for
Arraylist和LinkList的特点:
- LinkList特有的功能:
- set集合的概述和特点
1.不包含重复元素
2.没有带索引的方法,所以不能用普通for循环
package 实验;
import java.util.*;
public class collection {
public static void main(String[] args) {
Set<String> sc=new HashSet<String>();
sc.add("hello");
sc.add("world");
sc.add("java");
sc.add("java");
for(String s:sc){
System.out.println(s);
}
}
}
输出:
- 哈希值:
student s1=new student(参数,参数);
sout("s1.hashCode()");
sout("重地");1179395
sout("种地")1179395
1.同一对象的哈希值是相同的
2.默认情况下,哈希值不同,但是通过方法的重写,可以实现不同对象哈希值相同(String重写了hashCode方法)
- HashSet集合的概述和特点:
- HashSet保证元素唯一性的分析
要保证元素的唯一性,就需要重写hashCode()和equal()
(比如在student类中,就需要重写,alt+insert选中equal和hashcode后即可自动重写)???
(好像只是LinkedHashset才需要重写) - LinkedHashSet集合特点
- treese集合的特点:
package 实验;
import java.util.*;
public class collection {
public static void main(String[] args) {
TreeSet<Integer> ts =new TreeSet<Integer>();//<>中是包装类
ts.add(10);
ts.add(20);
ts.add(30);
ts.add(40);
ts.add(50);
ts.add(30);
for(Integer i : ts){
System.out.println(i);
}
Iterator<Integer> j=ts.iterator();
while(j.hasNext()){
System.out.println(j.next());
}
}
}
- 自然排序Comparable的使用:
package 实验;
import java.util.*;
public class collection {
public static void main(String[] args) {
TreeSet<student> ts =new TreeSet<student>();
student s1=new student ("张蔚原",19);
student s2=new student("蒋佳颖",20);
student s3=new student("许杰",19);
student s4=new student("余鑫",19);
student s5=new student("张蔚原",19);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
for(student i : ts){
System.out.println(i.getName()+","+i.getAge());
}
Iterator<student> j=ts.iterator();
while(j.hasNext()){
student k=j.next();
System.out.println(k.getName()+","+k.getAge());
}
}
}
此时会报错,学生类不能转化成自然排序接口,所以需要在student中实现comparable接口并重写
package 实验二;
import java.util.Objects;
public class student2 implements Comparable<student2> {
private String name;
private int age;
@Override
public int compareTo(student2 s) {
return 0;
}
public student2() {
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
student2 student2 = (student2) o;
return age == student2.age && Objects.equals(name, student2.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public student2(String name, int age) {
this.name = name;
this.age = age;
}
}
然后再测试函数中:
package 实验二;
import 实验.student;
import java.util.*;
public class text2 {
public static void main(String[] args) {
TreeSet<student2> ts =new TreeSet<student2>();
student2 s1=new student2 ("张蔚原",19);
student2 s2=new student2("蒋佳颖",20);
student2 s3=new student2("许杰",19);
student2 s4=new student2("余鑫",19);
student2 s5=new student2("张蔚原",19);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
for(student2 i : ts){
System.out.println(i.getName()+","+i.getAge());
}
System.out.println("---------");
Iterator<student2> j=ts.iterator();
while(j.hasNext()){
student2 k=j.next();
System.out.println(k.getName()+","+k.getAge());
}
}
}
但是此时的输出是:
原因是comparable中返回的值是0,说明元素是重复的,就不会再添加
如果返回值是一的话就会输出
张蔚原,19
蒋佳颖,20
许杰,19
余鑫,19
张蔚原,19
---------
张蔚原,19
蒋佳颖,20
许杰,19
余鑫,19
张蔚原,19
即使顺序输出
return -1的话就会逆置输出
@Override
public int compareTo(student2 k) {
int flag=this.age-k.age;//按年龄升序排列
int flag2=k.age-this.age;//按年龄降序
return flag;
}
当年龄相同时:
@Override
public int compareTo(student2 k) {
int flag=this.age-k.age;
int flag2=flag==0?this.name.compareTo(k.name):flag;//还能够防止重复
return flag2;
}
comparable比较器排序
package 实验二;
import 实验.student;
import java.util.*;
public class text2 {
public static void main(String[] args) {
TreeSet<student2> ts =new TreeSet<student2>(new Comparator<student2>() {
@Override
public int compare(student2 o1, student2 o2) {
int flag=o1.getAge()-o2.getAge();
int flag2=flag==0?o1.getName().compareTo(o2.getName()):flag;
return flag2;
}
});
student2 s1=new student2 ("张蔚原",19);
student2 s2=new student2("蒋佳颖",20);
student2 s3=new student2("许杰",19);
student2 s4=new student2("余鑫",19);
student2 s5=new student2("张蔚原",19);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
for(student2 i : ts){
System.out.println(i.getName()+","+i.getAge());
}
System.out.println("---------");
Iterator<student2> j=ts.iterator();
while(j.hasNext()){
student2 k=j.next();
System.out.println(k.getName()+","+k.getAge());
}
}
}
若 TreeSet ts =new TreeSet()为无参构造方法的话,即调用student中的:
@Override
public int compareTo(student2 k) {
int flag=this.age-k.age;
int flag2=flag==0?this.name.compareTo(k.name):flag;
return flag2;
}
余鑫,19
张蔚原,19
许杰,19
蒋佳颖,20
---------
余鑫,19
张蔚原,19
许杰,19
蒋佳颖,20
若TreeSet ts =new TreeSet(new Comparator()为带参构造方法:
(通过比较器进行排序就需要接受其接口的实现类对象,所以可以运用匿名内部类形式)
TreeSet<student2> ts =new TreeSet<student2>(new Comparator<student2>() {
@Override
public int compare(student2 o1, student2 o2) {
int flag=o1.getAge()-o2.getAge();
int flag2=flag==0?o1.getName().compareTo(o2.getName()):flag;
return flag2;
}
});
余鑫,19
张蔚原,19
许杰,19
蒋佳颖,20
---------
余鑫,19
张蔚原,19
许杰,19
蒋佳颖,20
- 案例:按照总成绩降序(主),语文成绩降序排序
泛型:
- 泛型类:
只需要一个类就能解决不同泛型而导致的不兼容问题:(T可以是任意类型)
package 泛型;
public class shiyan1<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
输出:
而如果不使用泛型类的话,实现上述需求就需要三各类中定义的get set方法来实现
- 泛型方法:
泛型接口:
可变参数:
package 泛型;
public class 可变参数 {
public static int sum(int ...a){
int sum=0;
for(int i:a){
sum+=i;
}
return sum;
}
}
package 泛型;
public class 可变参数text {
public static void main(String[] args) {
System.out.println(可变参数.sum(10,20,30,40));
System.out.println(可变参数.sum(20,30,40));
System.out.println(可变参数.sum(30,40));
}
}