字符串
【String、StringBuffer、StringBuilder区别】
1.String内容不可变,StringBuffer、StringBuilder内容可变
2.StringBuffer同步线程安全效率低,StringBuilder不同步数据线程不安全效率高
3.String1+String2 存在于不同的两个地址内存
Stringbuffer1.append(Stringbuffer2) 内存中是一个地址
【用法】
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
【String与StringBuffer/StringBuilder转换】
//1.String的构造方法
String str = new String(sbf);
//2.toString方法
sbf.toString();
//1.构造器
StringBuffer sbf = new StringBuffer(str);
//2.append方法
sbf.append(str);
集合**
Collection 单例集合根接口
-----|List 有序,可重复。
-------|ArrayList 底层是使用了Object数组实现 查询速度快,增删慢 线程不安全
-------|LinkedList 底层是使用了链表数据结构实现的 查询速度慢,增删快
-------|Vector 底层是使用了Object数组实现的, 线程安全的,操作效率低。
-----|Set 如果是实现了Set接口的集合类,具备的特点: 无序,不可重复。
-------|HashSet 底层是使用了哈希表实现 的。 特点: 存取速度快。
-------|TreeSet 底层是使用了二叉树结构实现的。 特点: 对集合中的元素进行排序存储
Map 双列集合根接口,key-value 的键值对,key 不允许重复,value 可以
-----|HashMap 底层也是使用了哈希表实现的 线程不安全
-----|TreeMap 底层也是使用了红黑树数据结构实现的。
-----|HashTable 底层也是使用了哈希表实现的,线程安全
【get遍历】
【迭代器遍历】
iterator()返回迭代器对象
迭代器遍历集合时,直接修改原集合会报ConcurrentModificationException
解决:采用迭代器操作或全部使用集合操作
【enterSet】
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
【集合方法】
add(T) //追加
add(index,T) //插入,index相同往前插入
set(index,T) //修改
泛型**
把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型
【好处】
1)类型安全
2)消除强制类型转换
3)提高性能
【注意】
1)泛型类型必须是引用类型,也就是说集合不能存储基本数据类型
2)泛型类不指定类型,默认Object
3)泛型类只能应用于非静态成员函数,静态函数需要在函数上独立声明
【泛型方法】
public
return o;
}
【泛型类】
修饰符 class 类名
}
【泛型接口】
interface Inter
public void show();
}
1)子类明确类型的泛型参数变量
class InterImpl implements Inter
public void show(){}
}
new InterImpl();
2)不明确类型的泛型参数变量
class InterImpl
public void show(){}
}
new InterImpl
【泛型通配符?】
如果参数之间的类型有依赖关系,或者返回值是与参数之间有依赖关系的。那么就使用泛型方法
如果没有依赖关系的,就使用通配符,通配符会灵活一些.
注意:使用通配符就只能调对象与类型无关的方法
public void printList2(List<?> list){
//o.add((T) "ft"); 就只能调对象与类型无关的方法,不能调用对象与类型有关的方法
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
【通配符限定】
? extends E: 接收E类型或者E的子类型。
?super E: 接收E类型或者E的父类型。
【泛型擦除】
编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息
语法注意**
【建包方式】
方式1:手动建包
方式2:自动建包
javac -d . hello.java //-d后面"."表示当前目录建立包
内部类**
【特点】
1)可以直接访问外部类成员,包括私有成员
2)公有数据域只能被外部类中的方法访问
【位置】
1)成员内部类
2)局部内部类
方法中定义的类,作用域仅在此方法
【内部类的字节码文件】
外部类$内部类.class
【调用方式】
1)外部类中new一个内部类对象
2)外部类.内部类 变量 = new 外部类对象.内部类对象
Outer.Inner oi = new Outer().new Inner();
【修饰符限定】
1)private 安全
2)static 方便
用static修饰,调用内部类格式(不能通过外部类对象限定)
外部类.内部类 变量 = new 外部类名.内部类名()
Outer.Inner oi = new Outer.Inner();
【局部内部类】
访问局部变量,局部变量必须final修饰(方法一旦结束,局部变量就会消失,所以为了延长局部变量的生命周期)
【匿名内部类】
没有名字的局部内部类
new 类或接口名(){
重写类方法或实现接口;
}
结果:是继承了类或实现了接口的匿名子类对象
常用用法:参数为接口或抽象类
IO流**
【字节流】
输入字节流:读数据
-----|InputStream 所有输入字节流的基类。 抽象类。
-------| FileInputStream 读取文件的输入字节流。
-------| BufferedInputStream 缓冲输入字节流,为了提高读取文件数据的效率。
输出字节流: 写数据
-----|OutputStream 所有输出字节流的基类。 抽象类。
-------| FileOutputStream 向文件输出数据 的输出字节流。
-------|BufferedOutputStream 缓冲输出字节流,为了提高向文件写数据的效率
【字符流】
输入字符流:读数据
-----|Reader 所有输入字符流的基类。 抽象类。
-------|FileReader 读取文件字符的输入字符流。
-------|BufferedReader 缓冲输入字符流,提高读取文件字符的效率并且拓展了功能(readLine())
输出字符流:写数据
-----|Writer 所有输出字符流的基类。 抽象类。
-------|FileWriter 向文件输出字符数据的输出字符流。
-------|BufferedWriter 缓冲输出字符流,提高写文件字符的效率并且拓展了功能(newLine())。
【转换流】
输入字节流的转换流 输入字节流---------输入字符流
InputSrteamReader
输出字节流的转换流
OutputStreamWriter
转换流的作用:
1. 可以把对应的字节流转换成字符流使用。
2. 可以指定码表进行读写文件的数据。
多线程**
创建方式:
方式一:继承Thread.
1. 自定义一个类继承Thread类。
2. 重写Thread的run方法,把自定义线程的任务代码定义在run方法上。
3. 创建Thread子类的对象,并且调用start方法启动一个线程。
方式二: 实现Runnable接口。
1. 自定义一个类实现Runnable接口。
2. 实现Runnable接口中的run方法,把自定义线程的任务代码定义在run方法上。
3. 创建Runable实现类 的对象。
4. 创建Thread对象,并且把Runnable实现类的对象作为参数传递。
5. 调用Thread对象的start方法开启线程。
线程安全 问题的解决方案:
1. 同步代码块
synchronized(锁){
需要被同步的代码
}
2. 同步函数。
修饰符 synchronized 返回值类型 函数名(形参列表..){
}
注意:
- 同步代码块的锁可以是任意的对象。 同步函数的锁是固定 的,非静态函数的锁对象是this对象。 静态函数的锁对象是class对象。
- 锁对象必须是多线程共享的对象,否则锁不住。
- 在同步代码块或者是同步函数中调用sleep方法是不会释放锁对象的,如果是调用了wait方法是会释放锁对象的。
---------------设计模式-------------------
【代理模式】为对象提供一种代理以控制对这个对象的访问
原有的对象需要额外的功能,想想动态代理这项技术!
--|静态代理
----|继承方式
----|聚合方式
--|动态代理
1)静态代理
2)动态代理
Proxy类的newInstance方法可以动态生成某个对象的代理对象
newInstance(代理类的装载器,代理类的接口,实现InvocationHandler接口)
InvocationHandler接口要实现invoke()方法,用户调用代理对象的方法都是在调用invoke方法
3)静态代理和动态代理的区别
静态代理需要自己写代理类-->代理类需要实现与目标对象相同的接口
而动态代理不需要自己编写代理类--->(是动态生成的)
【观察者模式】
本质:触发联动,当修改目标对象(天气)状态时,就会触发每个观察者(girl,mum收到信息)
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让他们能够自动更新
1)推模型:目标对象知道观察者需要的数据
2)拉模型:目标对象不知道观察者需要什么,因此将自身传递给观察者,由观察者取值