泛型
泛型的好处
1.把运行期间出现的问题提前到编译期间
2.避免了无谓的强制类型转换-注意:
在泛型中没有多态的概念,两边的数据必须一致,或者只写一边。自定义泛型:可以理解为一个占位符。
泛型方法:
格式:
**修饰符 <声明自定义泛型>返回值类型 函数名(形参列表..){
}**
注意:
在方法上的自定义泛型的具体数据类型是调用该方法的时候传入实参时候确定的。
自定义泛型使用的标识符只要符合表示符的命名规则即可。public class Demo2{ public static void main(String[] arga){ Integer i = print(12); String str = print("abc"); } public static <abc> abc print(abc o){ retrun o; } }
泛型类
class 类名<声明自定义的泛型>{}
注意事项:
在类上自定义的泛型的具体数据类型是在创建对象的时候指定的
在类上定义了泛型,在创建该类的对象时候没有指定泛型的具体类型,那么默认是Object类型class Worker implements Comparator<Worker>{ public int compare(Worker o1, Worker o2){ retrun 0; } }
自定义一个集合对象
class MyList<T>{ Object[] array = new Object[10]; int index = 0; public MyList(){ } public void add(T o){ arr[index++] = o; } } public class Demo3{ public static void main(String[ ] args){ MyList<String> list = new MyList<String>; list.add("12"); } }
泛型接口
泛型接口的定义格式:
interface 接口名<声明自定义的泛型>{}
注意事项:
1.在泛型上自定义的具体数据类型是实现该接口的时候指定的。
2.如果一个接口自定义了泛型,在实现该接口的时候没有指定具体的数据类型,那么默认是OBject数据类型。
interface Dao<T>{
public void add(T t);
public void remove(T t);
}
public class Demo4<T> implements Dao<T>{
public static void main(String[] args){
new Demo4<String>();
}
@Override
public void add(T t) {
// TODO Auto-generated method stub
}
@Override
public void remove(T t) {
// TODO Auto-generated method stub
}
}
IO流
字节流:
输入字节流:
InputStream 所有输入字节流的基类,抽象类
FileInputStream 读取文件的输入字节流
BufferedInputInstream 缓冲输入字节流,该类的内部维护了8kb的字节数组,提高效率。
输出字节流:
OutputStream 所有输出字节流.抽象类
FileOutputStream 向文件中输出字节流
BufferedOUtputStream 缓冲字节流。提高文件的写数据的效率
什么时候使用字节流:读取到的数据不需要编码或者解码的情况下使用字节流。
字符流=字节流+编码(解码)
字符流
输入字符流
Reader:所有输入字符流的基类,抽象类
FileReader:读取文件字符的输入字符流
BufferedReader:缓冲字符流。
输出字符流:
Writer 所有输出字符流的基类。抽象类。
FileWriter 读取文件的输出字符流
BufferedWriter 缓冲输出字符流。转换流
InputStreamReader
OutputStreamWriter
转换流的作用:
1.把对应的字节流转换成字符流使用
2.可以指定码表读写数据
注意:
FileReader,FileWriter这两个类默认是使用gbk编码表,不能指定码表读写文件数据。public static void testInput() throws Exception{ InputStream in = System.in; //需要把字节流转换成字符流使用 InputStreamReader inputStreamReader = new InputStreamReader(in); //把子符流包装成高效字符流 BufferedReader bufferedReader = new BufferedReader(inputStreamReader ); //使用readLine()方法 System.out.println(bufferedReader.readLine()); }
//将字节流包装成字符流后,使用write()方法写一个字符
public static void testOutput() throws Exception{
Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
//获取socket的输出流对象
OutoutStream os = socket.getOutputStream();
//把输出字节流转换成为字符流
OutputStreamWiter osw = new OutputStreamWiter (os);
//调用write()方法
os.write("安徽省");
指定编码表编写数据
public static void writeFile() throws IOException{
//建立了文件和程序的通道
FileOutputStream fos = new FileOutputStream("F:\\a.txt");
//创建一个输出字节流的转换流并且指定编码表写数据
OutputStreamWriter osw = new OutputStream(fos, "UTF-8");
osw.write("大家哈哈");
outputStreamWriter.close();
}
public static void readFile() throws IOException{
//建立文件与程序的输入数据通道
FileInputStream fileInputStream = new FileInputStream("F:\\a.txt");
//创建输入字节流的转换流并且指定码表进行读取
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
int content = 0;
while((content = inputStreamReader.read())!=-1){
System.out.println((char)content);
}
//关闭资源
inputStreamReader.close();
}
集合
集合:存储对象数据的集合容器
单例集合:
Collecton单例集合根接口
List 特点:有序,可重复
ArrayList:底层使用了Object数组实现的。特点查询块,增删慢
LinkedList:底层使用了链表数据结构的实现。特点:查询慢,增删块。
Vector:与ArrayList区别是线程安全,效率低。
hashSet存储元素的原理
在hashSet中填写元素的时候,首先会调用hashCode方法的哈希值,然后把哈希值经过运算算出该元素在哈希表中的位置。
情况1:如果算出的位置目前还没有任何的元素,直接添加。
情况2:如果算出的元素已经存在其他元素,那么调用equals方法在和这个位置上的元素比较一次。true不添加,false则添加。
TreeSet要注意的事项:
1.在TreeSet添加元素的时候,如果元素具备自然顺序的话,那么TreeSet会根据元素的自然顺序进行排序存储。
2.在TreeSet添加元素的时候,如果元素不具备自然排序的特点,那么元素所属于的类必须实现Comparable
接口,把比较的规则·定义在CompareTo()方法上。
3..在TreeSet添加元素的时候,如果元素不具备自然排序的特点,那么元素所属于的类没有实现Comparable
接口,那么在创建TreeSet对象的时候,必须把把比较器对象对位参数传递。
比较器定义的模式:
class 类名 implements Comparator{
}
双列集合:Map 存储的数据都是以键值对的形式存在,
键不能重复,值可以
HashMap 底层使用哈希表实现
TreeMap:底层使用红黑树数据结构实现。
线程
方式一:继承Thread
1.自定义一个类继承Thread类。
2.重写Thread类的run()方法,并且把自定义的任务代码写在run()方法上。
3.创建Thread的子类,并且调用start()方法;
方式二:实现Runnable接口
1.自定义一个类实现Runnable接口
2.实现Runnable接口中的run方法,把自定义线程任务代码定义在run方法上。
3.创建Runnable实现类对象
4.创建Thread对象,并且把Runnable实现类作为参数传递。
5.调用start()方法且开始线程。
同步代码块
synchronized(锁){
需要被同步的代码块
}同步函数
修饰符 synchronized 返回值类型 函数名(形参列表…){}
注意
- 同步代码块的锁是任意对象。同步函数的锁是固定的,非静态函数的锁对象是this对象,静态函数的锁是class对象。
- 锁对象必须是多线程共享上网·对象
-在同步代码块或者同步函数中调用sleep方法是不释放锁的,但是调用了wait()方法是会释放锁。