☆JAVA技能
«有良好的JAVA基础,熟练掌握面向对象思想:
理解面向对象:
面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。面向对象有三大特征:封装性、继承性、多态性,其中封装性指的是隐藏了对象的属性和实现细节,仅对外提供公共的访问方式,这样就隔离了具体的变化,便于使用,提高了复用性和安全性。对于继承性,就是两种事物间存在着一定的所属关系,那么继承的类就可以从被继承的类中获得一些属性和方法;这就提高了代码的复用性。继承是作为多态的前提的。多态是说父类或接口的引用指向了子类对A象,这就提高了程序的扩展性,也就是说只要实现或继承了同一个接口或类,那么就可以使用父类中相应的方法,提高程序扩展性,但是多态有一点不好之处在于:父类引用不能访问子类中的成员。
举例来说:就是:比如说你要去饭店吃饭,你只需要饭店,找到饭店的服务员,跟她说你要吃什么,然后叫会给你做出来让你吃,你并不需要知道这个饭是怎么错的,你只需要面向这个服务员,告诉他你要吃什么,然后他也只需要面向你吃完收到钱就好,不需要知道你怎么对这个饭进行吃。
1、特点:
1:将复杂的事情简单化。
2:面向对象将以前的过程中的执行者,变成了指挥者。
3:面向对象这种思想是符合现在人们思考习惯的一种思想。
2、面向对象的三大特征:封装,继承、多态
1.封装:只隐藏对象的属性和实现细节,仅对外提供公共访问方式
好处:将变化隔离、便于使用、提高复用性、提高安全性
原则:将不需要对外提供的内容隐藏起来;把属性隐藏,提供公共方法对其访问
2.继承:提高代码复用性;继承是多态的前提
注:
①子类中所有的构造函数都会默认访问父类中的空参数的构造函数,默认第一行有super();若无空参数构造函数,子类中需指定;另外,子类构造函数中可自己用this指定自身的其他构造函数。
3.多态
是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象
好处:提高了程序的扩展性
弊端:当父类引用指向子类对象时,虽提高了扩展性,但只能访问父类中具备的方法,不可访问子类中的方法;即访问的局限性。
前提:实现或继承关系;覆写父类方法。
«熟练使用集合、IO流及多线程
一、集合:
1、特点:存储对象;长度可变;存储对象的类型可不同;
2、集合框架:
2)Collection
(1)List:有序的;元素可重复,有索引
(add(index,
element)、add(index,
Collection)、remove(index)、set(index,element)、get(index)、subList(from, to)、listIterator())
①ArrayList:底层是数组结构,查询快,增删慢,不同步。
②LinkedList:底层是链表结构,增删快,查询慢,不同步
addFist();addLast()getFirst();getLast()
removeFirst();removeLast()获取并删除元素,无元素将抛异常:NoSuchElementException
替代的方法(JDK1.6):
offerFirst();offerLast();
peekFirst();peekLast();无元素返回null
pollFirst();pollLast();删除并返回此元素,无元素返回null
③Vector:底层是数组结构,线程同步,被ArrayList取代了
注:了对于判断是否存在,以及删除等操作,以依赖的方法是元素的hashCode和equals方法
ArrayList判断是否存在和删除操作依赖的是equals方法
(2)Set:无序的,无索引,元素不可重复
①HashSet:底层是哈希表,线程不同步,无序、高效
保证元素唯一性:通过元素的hashCode和equals方法。若hashCode值相同,则会判断equals的结果是否为true;hashCode不同,不会调用equals方法
LinkedHashSet:有序,是HashSet的子类
②TreeSet:底层是二叉树,可对元素进行排序,默认是自然顺序
保证唯一性:Comparable接口的compareTo方法的返回值
===》TreeSet两种排序方式:两种方式都存在时,以比较器为主
第一种:自然排序(默认排序):
添加的对象需要实现Comparable接口,覆盖compareTo方法
第二种:比较器
添加的元素自身不具备比较性或不是想要的比较方式。将比较器作为参数传递进去。
定义一个类,实现Comparator接口,覆盖compare方法。当主要条件相同时,比较次要条件。
3)Map集合:
(1)HashTable:底层数据结构是哈希表,不可存入null键和null值。同步的
Properties继承自HashTable,可保存在流中或从流中加载,是集合和IO流的结合产物
(2)HashMap:底层数据结构是哈希表;允许使用null键和null值,不同步,效率高
TreeMap:
底层数据结构时二叉树,不同步,可排序
与Set很像,Set底层就是使用了Map集合
方法:
V put(K key, V value);void putAll(Map m)
void clear();V remove(Object key)
booleancontainsKey(Object key);containsValue(Object key);isEmpty()
V get(Object key); intsize(); Collection values()
SetkeySet();Set> entrySet()
2.3、Map集合两种取出方式:
第一种:Set keySet()
取出Map集合中的所有键放于Set集合中,然后再通过键取出对应的值
Set keySet= map.keySet();
Iteratorit = keySet.iterator();
while(it.hasNext()){
String key = it.next();
String value = map.get(key);
//…..
}
第二种:Set> entrySet()
取出Map集合中键值对的映射放于Set集合中,然后通过Map集合中的内部接口,然后通过其中的方法取出
Set>entrySet = map.entrySet();
Iterator>it = entrySet.iterator();
While(it.hasNext()){
Map.Entry entry = it.next();
String key = entry.getKey();
String value = entry.getValue();
//……
}
2.4、Collection和Map的区别:
Collection:单列集合,一次存一个元素
Map:双列集合,一次存一对集合,两个元素(对象)存在着映射关系
2.5、集合工具类:
Collections:操作集合(一般是list集合)的工具类。方法全为静态的
sort(List list);对list集合进行排序;
sort(List list, Comparator c)按指定比较器排序
fill(List list, T obj);将集合元素替换为指定对象;
swap(List list, int I,
int j)交换集合指定位置的元素
shuffle(List list);随机对集合元素排序
reverseOrder():返回比较器,强行逆转实现Comparable接口的对象自然顺序
reverseOrder(Comparator
c):返回比较器,强行逆转指定比较器的顺序
2.6、Collection和Collections的区别:
Collections:java.util下的工具类,实现对集合的查找、排序、替换、线程安全化等操作。
Collection:是java.util下的接口,是各种单列集合的父接口,实现此接口的有List和Set集合,存储对象并对其进行操作。
3、Arrays:
用于操作数组对象的工具类,全为静态方法
asList():将数组转为list集合
好处:可通过list集合的方法操作数组中的元素:
isEmpty()、contains()、indexOf()、set()
弊端:数组长度固定,不可使用集合的增删操作。
如果数组中存储的是基本数据类型,asList会将数组整体作为一个元素存入集合
集合转为数组:Collection.toArray();
好处:限定了对集合中的元素进行增删操作,只需获取元素
二、IO流
1、结构:
字节流:InputStream,OutputStream
字符流:Reader,Writer
Reader:读取字符流的抽象类
BufferedReader:将字符存入缓冲区,再读取
LineNumberReader:带行号的字符缓冲输入流
InputStreamReader:转换流,字节流和字符流的桥梁,多在编码的地方使用
FileReader:读取字符文件的便捷类。
Writer:写入字符流的抽象类
BufferedWriter:将字符存入缓冲区,再写入
OutputStreamWriter:转换流,字节流和字符流的桥梁,多在编码的地方使用
FileWriter:写入字符文件的便捷类。
InputStream:字节输入流的所有类的超类
ByteArrayInputStream:含缓冲数组,读取内存中字节数组的数据,未涉及流
FileInputStream:从文件中获取输入字节。媒体文件
BufferedInputStream:带有缓冲区的字节输入流
DataInputStream:数据输入流,读取基本数据类型的数据
ObjectInputStream:用于读取对象的输入流
PipedInputStream:管道流,线程间通信,与PipedOutputStream配合使用
SequenceInputStream:合并流,将多个输入流逻辑串联。
OutputStream:此抽象类是表示输出字节流的所有类的超类
ByteArrayOutputStream:含缓冲数组,将数据写入内存中的字节数组,未涉及流
FileOutStream:文件输出流,将数据写入文件
BufferedOutputStream:带有缓冲区的字节输出流
PrintStream:打印流,作为输出打印
DataOutputStream:数据输出流,写入基本数据类型的数据
ObjectOutputStream:用于写入对象的输出流
PipedOutputStream:管道流,线程间通信,与PipedInputStream配合使用
2、流操作规律:
明确源和目的:
数据源:读取,InputStream和Reader
目的:写入:OutStream和Writer
数据是否是纯文本:
是:字符流,Reader,Writer
否:字节流,InputStream,OutStream
明确数据设备:
源设备:内存、硬盘、键盘
目的设备:内存、硬盘、控制台
是否提高效率:用BufferedXXX
3、转换流:将字节转换为字符,可通过相应的编码表获得
转换流都涉及到字节流和编码表
三、多线程
--à进程和线程:
1)进程是静态的,其实就是指开启的一个程序;而线程是动态的,是真正执行的单元,执行的过程。其实我们平时看到的进程,是线程在执行着,因为线程是作为进程的一个单元存在的。
2)同样作为基本的执行单元,线程是划分得比进程更小的执行单位。
3)每个进程都有一段专用的内存区域。与此相反,线程却共享内存单元(包括代码和数据),通过共享的内存单元来实现数据交换、实时通信与必要的同步操作。
1、创建线程的方式:
创建方式一:继承Thread
1:定义一个类继承Thread
2:覆盖Thread中的run方法(将线程运行的代码放入run方法中)。
3:直接创建Thread的子类对象
4:调用start方法(内部调用了线程的任务(run方法));作用:启动线程,调用run方法
方式二:实现Runnable
1:定义类实现Runnable接口
2:覆盖Runnable接口中的run方法,将线程的任务代码封装到run中
3:通过Thread类创建线程对象
4、并将Runnable接口的子类对象作为Thread类的构造函数参数进行传递
作为参数传递的原因是让线程对象明确要运行的run方法所属的对象。
区别:
继承方式:线程代码放在Thread子类的run方法中
实现方式:线程存放在接口的子类run方法中;避免了单继承的局限性,建议使用。
2、线程状态:
新建:start()
临时状态:具备cpu的执行资格,但是无执行权
运行状态:具备CPU的执行权,可执行
冻结状态:通过sleep或者wait使线程不具备执行资格,需要notify唤醒,并处于临时状态。
消亡状态:run方法结束或者中断了线程,使得线程死亡。
3、多线程安全问题:
多个线程共享同一数据,当某一线程执行多条语句时,其他线程也执行进来,导致数据在某一语句上被多次修改,执行到下一语句时,导致错误数据的产生。
因素:多个线程操作共享数据;多条语句操作同一数据
解决:
原理:某一时间只让某一线程执行完操作共享数据的所有语句。
办法:使用锁机制:synchronized或lock对象
4、线程的同步:
当两个或两个以上的线程需要共享资源,他们需要某种方法来确定资源在某一刻仅被一个线程占用,达到此目的的过程叫做同步(synchronization)。
同步代码块:synchronized(对象){},将需要同步的代码放在大括号中,括号中的对象即为锁。
同步函数:放于函数上,修饰符之后,返回类型之前。
5、wait和sleep的区别:(执行权和锁区分)
wait:可指定等待的时间,不指定须由notify或notifyAll唤醒。
线程会释放执行权,且释放锁。
sleep:必须制定睡眠的时间,时间到了自动处于临时(阻塞)状态。
即使睡眠了,仍持有锁,不会释放执行权。