=======================集合(II)===================
泛型集合:强制集合中的类型必须统一。
为了防止类型转换异常。
工具类(Collections):提供了一些对集合/数组的一些简单操作:排序。
public static void reverse(List<?> list)//进行倒序
public static void shuffle(List<?> list)//随机产生顺序
public static void sort(List<T> list)//按照一定的规则进行排序
需要排序规则
lang包中的规则:Comparable接口
实现compareTo方法;
//比较 this 和 指定对象stu的大小
//this > stu 返回>0
//this < stu 返回<0
//this == stu 返回=0
public int compareTo(Student stu){
if(this.age >stu.age)
return 1;
else if(this.age<stu.age)
return -1;
else {
return 0;
}
}
三、set接口
1、特点
元素无顺序,无下标,不可以重复。
2、方法
从Collection继承来的所有方法。
3、遍历
for-each
迭代器
4、实现类
1)HashSet
如果要实现HashSet中元素的值不重复。
1,覆盖HashCode
确保相同的对象 返回相同的int值(HsahCode值)
为了提高效率,尽量做到不同的对象 返回不同的int值。
通常把对象的属性值加到一起,如果是对象类型 调用该对象的HashCode方法。
2.覆盖equals
当在同一位置上已经存在集合元素时,会再调用equals方法,判断2个对象的内容是否相同,
如果相同则拒绝加入集合。
2)TreeSet
实现了SortedSet接口,也是Set的子接口
自动进行排序。
排重:实现java.lang.Comparable接口,实现接口中的方法compareTo方法。如果返回值0,重复了就不会添加。
四、Map接口
1.特点
存放任意的键值对(Key----Value)。
键:无序,无下标,元素不可重复。(键是唯一的)
值:无序,无下标,元素可以重复。
2.方法
V put(K key, V value)//往map中添加一个元素,假如键已经存在,会覆盖原有的值
V remove(Object key)// 根据键删除对应的键值对。
V get(Object key)// 根据键获得对应的值。
boolean containsKey(Object key) //判断Map集合中是否包含指定的键。
boolean containsValue(Object value) //判断Map中是否包含指定的值。
3.遍历
1.键遍历
Set<K> keySet()
2.值遍历
Collection<V> values()
3.键值对
Set<Map.Entry<K,V>> entrySet()
4.实现类
1)hashMap(假如键为自定义类型,需要覆盖hashCode和equals方法,保证键唯一)
jdk1.2 线程不安全,快
允许key和value都为null
2) hashTable
jdk1.0 线程安全,慢
允许key和value都不为null
3)Properties
是hashTable的一个子类,要求key和value必须都为String类型。
多数用于 读取配置文件。
4)TreeMap
实现了SortedMap接口,是Map的子类。会根据键进行排序。
实现Compareble接口,实现里面的compareTo方法。返回值是0,覆盖了原有的值。
集合小结
Collection
list Set
有序 无序
有下标 无下标
可以重复 不可重复
Map
键值对
键:无序,无下标,不可重复(键唯一)
值:无序,无下标,可以重复
LinkedList和ArrayList的区别?
链表 查询慢,增删快
数组 查询快,增删慢
ArrayList和Vector的区别?
1.2 线程不安全,快,轻量级
1.0 线程安全,慢,重量级
HashMap 和Hashtable的区别?
jdk1.2 线程不安全,快
允许key和value都为null
jdk1.0 线程安全,慢
允许key和value都不为null
Hashtable和Properties的区别?
泛型集合的好处?
数据安全。强制集合中的类型必须统一
HashSet和TreeSet分别如何实现 元素不重复?
Collection和Collections的区别?
list:
1.下标遍历
list.add();
for(int i=0;i<list.size();i++){
}
2.Iterator迭代遍历
Iterator in=list.interator();
while(in.hasNext()){
Obeject o=in.next();
}
3.for(Object o: list ){}
Set
Map:
1.键遍历
Set<K> set=map.keySet()
2.值遍历
Collection<V> con=map.values()
3.键值对遍历
Set<Map.Entry<K,V>> entrySet =map.entrySet();
========================异常==========================
异常:程序运行过程中,出现的错误,例外。
异常处理:异常发生之后,会执行一段预先写好的代码,减少损失。
一、异常分类
Throwable
|-Error 错误,底层代码出现严重问题,无法避免,程序员无法解决,无需程序员来解决
|-Exception 异常
|-RuntimeException 运行时异常/未检查异常 编译时忽略 可以避免 可以处理也可以不处理
|-IndexOutOfBoundsException
|-NullPointerException
|-ClassCastException
|-非RuntimeException 非运行时异常/已检查异常 编译时会出错,必须要处理
二、异常的产生和传递
1.异常的产生
1)自动产生
程序运行时,遇到出错的代码,自动产生异常,程序自动终止。
2)手动产生
throw new 异常名称(实参);//手动抛异常,必须定义在方法以内。
程序执行到手动抛异常,会把 throw 后面 new 的异常对象抛出,程序自动终止。
2.异常的传递
异常堆栈信息:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Day17.TestException.m3(TestException.java:24)
at Day17.TestException.m2(TestException.java:19)
at Day17.TestException.m1(TestException.java:14)
at Day17.TestException.main(TestException.java:9)
程序因异常终止后,会以 函数的调用的反方向 进行传递。
三、异常的处理【重点】
1.消极的处理(声明异常)
语法:(定义在方法声明的后面)
修饰符 返回值类型 方法名(形参列表) throws 异常的名称1, 异常的名称2... {
//方法体
}
使用throws 只是消极的把异常继续往后传递,并没有解决问题。
2.积极地处理(捕获异常)
try{
//可能出现异常的语句
}catch(IOException e){
//处理异常的语句
}finally{
//一定会被执行。
}
注意:1)try后面可以跟多个catch,但是父类异常必须放到后面。
2)catch可以捕获异常,可能出现非RuntimeException或者runtimeException
3)finally 中的语句,一定会被执行。
try...catch...
try...catch...finally...
try...finally...
try...catch...catch...catch...
try...catch...catch...catch...finally...
try...(try...catch...finally...)...catch...(try...catch...finally...)...finally...(try...catch...finally...)...
消极处理和积极处理是可以搭配使用。
四、自定义异常类
public class MyException extends Exception {
MyException (){}
MyException(String msg){
super(msg);
}
}
五、方法的覆盖
1.语法要求:方法名,返回值类型,形参列表必须相同。
2.访问修饰符 可同或更宽。
3.子类的方法中,不允许抛出更多、更广的异常。
=======================================线程=========================================
一、概念
进程:操作系统中,并发执行的任务。
并发执行原理:宏观并行,微观串行。
线程:在一个进程中,并发执行的多个程序逻辑。
主线程:main函数。
特点:多线程中,先后顺序不确定。
不因任何线程结束而结束。
线程的组成:
1)CPU 操作系统(OS)选中。
2)内存分配
栈空间 局部变量 独立
堆空间 new 对象 被所有的线程所共享。
3)代码
1.继承 Thread 父类。
覆盖run方法。
创建线程对象:MyThread1 t1 = new MyThread1();
启动线程:t1.start();
2.实现Runnable 接口
实现run方法
创建线程对象:
//创建目标对象
Target t = new Target();
//创建线程对象
Thread t2 = new Thread(t);
启动线程:
t2.start();
二、线程的状态
详情,请看线程状态图
三、线程同步/安全[重点]
临界资源:多线程并发时,共享的一个对象
原子操作:要执行的代码 作为一个整体,如果执行则执行,如果不执行则不执行。
线程同步/安全:多线程并发时,为了保证临界资源的正确性,而不破坏 代码的原子操作。
线程同步的2种方法:
synchronized
1)同步代码块
使用在方法内部,语法:
synchronized (临界资源对象){
//原子操作
}
线程 只有获取到 临界资源对象的锁标记,才能执行后面{}中的代码,
并且必须等{}中的所有代码都执行完,才释放该对象的锁标记。
如果 没有获取到 临界资源对象的锁标记,则该线程处于 等待状态(锁池状态)。
直到拿到锁标记,才能执行代码块。
2)同步方法
synchronized 修饰方法
synchronized 返回值类型 方法名(形参){
//原子操作
}
等同于:
synchronized (this){
//原子操作
}
四、线程间的通信(等待-通知)【了解】
obj.wait();
注意:1.必须放在 对该对象操作的同步代码块中。
2.调用wait方法之后,线程就进入了等待状态(等待队列状态)
3.进入等待状态后,该线程会释放获取到的锁标记,同时也会交出CPU。
obj.notify()/obj.notifyAll();
注意:1.必须放在 对该对象操作的同步代码块中。
2. 通知其他线程 可以从等待队列状态出来,
一旦获取到CPU,同时会获得锁标记,该线程就可以执行。
五、
1、ArrayList 和 Vector的区别?
ArrayList: JDK 1.2 线程不安全 效率高
Vector: JDK 1.0 线程安全 效率低
2、synchronized 能修饰 构造方法、抽象方法、static方法吗?
修饰构造方法:不能,构造方法执行时,对象尚未创建。
修饰抽象方法:不能,抽象方法没有实现部分。
修饰静态方法:能, 对 类对象 加锁。
================================I/O 字节流=====================================
一、流的概念
持久化:把数据从内存中往其他存储设备中 存储的过程
流:数据传输的通道、管道。
流的分类:
1)从方向
输入流,输出流。
2)从传输内容
字节流:可以操作所有类型文件。
字符流:可以操作文本类型的文件。
3)从功能
节点流: 具有 基本的读写功能。
过滤流:在节点流的基础上,添加了一些新的功能。
二、字节流
父类:InputStream/OutputStream 抽象类
节点流:
FileInputStream/FileOutputStream 文件字节输入流/文件字节输出流【重点】
过滤流:
DataInputStream/DataOutputStream 操作8种基本类型 字符串readUTF()/writeUTF()
BufferedInputStream/BufferedOutputStream 缓冲
ObjectInputStream/ObjectOutputStream 对 对象的读写操作 操作8种基本类型 字符串readUTF()/writeUTF()
1.FileOutputStream
void write(int b)
1次写1个字节的内容,把字节b的内容,写入流对应的文件中。
void write(byte[] b)
1次写多个字节的内容,把b数组的所有内容,写入流对应的文件中。
void write(byte[] b, int off, int len)
1次写多个字节的内容,把b数组的部分内容(从下标off开始,到长度为len),
写入流对应的文件中。
2.FileInputStream
int read()
1次读1个字节,返回读到的字节内容。
int read(byte[] b)
1次读多个字节,并且把读到的内容存放在b数组中,返回实际读到字节的个数,
如果到结尾,返回-1
int read(byte[] b, int off, int len)
1次读多个字节,并且把读到的内容存放在b数组的
指定位置(从下表off开始,长度len),返回实际读到的字节的个数,
如果到结尾,返回-1
3.ObjectInputStream/ObjectOutputStream
对象序列化:把对象 在内存 和其他存储设备间进行传输【重点】
注意:
1)对象序列化,必须保证 该对象时可序列化的。
类 必须实现 java.io.Serializable 接口。
2)Object obj=ois.readObject();//读取一个对象
如果出现java.io.EOFException,则代表读到结尾。
3)transient 修饰的属性,不参与序列化。
4)如果对象的属性,又是自定义的对象,则该对象也必须是可序列化的。
5)如果对集合序列化,必须保证 该集合中所有元素师可序列化的。
================================I/O 字符流=====================================
一、编码方式
ISO8850-1 西欧
GBK 中国简体中文
GBK18030
GBK2312
BIG5 繁体中文
UTF-8 万国码 bytes1,2,3随机分配。
乱码:
字符的编码方式 和解码方式 不一致,可能就造成乱码。
二、字符流
父类:Reader/Writer 抽象类
节点流:FileReader/FileWriter 文件输入/输出
过滤流:BufferedReader/PrintWriter 缓冲、8种基本类型、字符串、对象
桥转换流:InputStreamReader/OutputStreamWriter[重点]
字节--》字符 转换的桥梁,同时可以设置字符编码集。
三、File 文件
IO流:对文件中的内容,进行操作。
File:对文件自身进行操作。如:删除文件,改名,改为只读等。
File代表 文件或者文件夹。
//创建
f.createNewFile()
//删除
f.delete()
//改名
File ff=new File("ff.txt");
f.renameTo(ff)
练习:
列出d:/根目录下 所有以.java 结尾的文件名。
f.getName();
f.getAbsolutePath();
File[] fs=f.listFiles();//获取当前File文件夹根目录下的所有文件/文件夹。
=============================网络编程===================================
一、网络编程
IP地址:在网络中主机的唯一标识,逻辑标识。
MAC地址:在网络中主机的唯一标识,物理标识。
协议:网络中 信息共享 必须遵循的规范。
OSI 七层模型:
物理层
数据链路层
网络层 IP
传输层 TCP UDP
会话层
表式层
应用层 http ftp smtp pop
TCP:传输控制协议, 连接(有序,不乱不丢)
UDP:用户数据报协议,无连接(无序,会乱会丢)
Oracle:
端口号:用于区分 同一台主机上的 不同进程。
基于TCP的网络编程:
1.服务器端
//创建服务器对象,同时指定端口号
//等待Client请求
//读写操作
//关闭Client
2.客户端
//创建Client对象,同时指定要请求的Server的IP和port
//读写操作
//关闭Client
========================单例模式【重点】===========================
设计模式:是经验的总结,不限制使用语言。
单例:只创建一个对象。
饿汉式 懒汉式
=============================反射【难点】====================================
类的对象:基于定义好的类,创建该类的一个实例对象。
类对象:类加载的产物。
一、获取类对象。(三中方法)
1)使用类名
类名.class
2)使用静态方法
Class.forName("包名.类名");
3)使用类的对象。
Student s=new Student();
s.getClass();
二、基于类对象,创建类的对象。
c.newInstance();
//根据给定的字符串类名,创建出该类的对象。
public Object createInstance(String className){
Class c=Class.forName(className);
return c.newInstance();
}
//根据给定的字符串类名,找到该类的所有方法(类似于MyEclipes “.”)
public void getMethods(String className){
Class c=Class.forName(className);
Method[]ms= c.getMethods();
}