Java提升2
2017-01-05 09:38
225 查看
一. Java集合类详解
Connection接口集合可以理解为一个动态的对象数组,不同的是集合中的对象内容可以任意扩充
集合的特点:
性能高
容易扩展和修改
Collection的常用子类
List
Set
Queue
List接口
List接口可以存放任意的数据,而且在List接口中内容是可以重复的
List接口常用子类:
ArrayList
Vector
常用操作:
判断集合是否为空:boolean isEmpty()
查找指定的对象是否存在:int indexOf(Object o)
比较 | ArrayList | Vector |
---|---|---|
推出时间 | JDK1.2之后推出 | JDK1.0推出 |
性能 | 采用异步处理方式,性能高 | 采用同步处理方式,性能低 |
线程安全 | 属于非线程安全 | 属于线程安全 |
Set接口中不能加入重复元素,但是可以排序
Set接口常用子类
散列存放:HashSet
有序存放:TreeSet
Iterator接口
集合输出的标准操作:
标准做法,使用Iterator接口
操作原理:
Iterator是专门的迭代输出接口,迭代输出就是将元素一个个进行判断,判断其是否有内容,如果有内容则把内容取出。
Map接口
保存形式:
Key—>value的方式保存
常用子类:
HashMap:无序存放,key不允许重复(非线程安全的)
Hashtable:无序存放,key不允许重复(线程安全的)
二. Java中的IO操作
作用:IO也写作“I/O”,可理解为In和Out,即输入与输出。所以,IO体系的基本功能就是:读和写。
IO流
作用:读写设备上的数据,硬盘文件、内存、键盘、网络…
根据数据的走向,可分为:输入流、输出流
根据处理的数据类型,可分为:字节流、字符流
字节流和字符流
字节流可以处理所有类型的数据,如MP3,图片、文字、视频等。在读取时,读到一个字节就返回一个字节。
在java中对应的类都以“Stream”结尾。
字符流仅能处理纯文本数据,如txt文本等。在读取时,读到一个或者多个字节,先查找指定的编码表,然后将查到的字符返回。
在Java中对应的类都以“Reader”或“Writer” 结尾
字符、字节和编码
字节(Byte)
字节是通过网络传输信息或再硬盘或内存中存储信息的单位,是计算机信息技术用于计量存储容量和传输容量的一种计量单位。
1个字节等于8位二进制,即一个8位二进制数,是一个狠具体的存储空间。
如0x01,0x45,0xFA,…
字符(Char)
字符是人们使用的几号,抽象意义上的一个符号。
如’1’,’中’,’a’,’¥’,’$’,…
字符集(Charset)
“字符集”也称为“编码”。
三者的区别,请看下表:
![](https://raw.githubusercontent.com/williamHappy/FileRepo/master/hexo/20161124/Java003/img/javaByteCharDif.png)
5. 使用字节流读写数据
使用fileInputStream和fileOutputStream来进行文件的拷贝
public static void main(String[] args) { try { FileInputStream fileInputStream = new FileInputStream("Java01/text.txt"); FileOutputStream fileOutputStream = new FileOutputStream("Java01/newText.txt"); byte input[] = new byte[50]; while (fileInputStream.read(input) != -1) { fileOutputStream.write(input); } fileInputStream.close(); fileOutputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
6. 使用带缓冲的字节流读写数据
public static void main(String[] args){ try { FileInputStream fileInputStream = new FileInputStream("Java01/text.txt"); BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream,1000000);//设置缓冲区的大小 //大型文件对应的数组可以大一些,小文件对应的数组小一些 byte input[] = new byte[100000]; int count = 0; long before = System.currentTimeMillis(); //读取之前的时间 while (bufferedInputStream.read(input)!=-1){ count++; } bufferedInputStream.close(); fileInputStream.close(); System.out.println(System.currentTimeMillis()-before+"ms"); //读取之后和之前的差值 System.out.println("都去了"+ count +"次"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
说明:通过多次调试缓冲区和字节数组的大小,来寻找文件读取效率最高的数据。
7. 使用字符流读写数据
同样是,进行文件拷贝,现在使用字符流来读写数据,实例如下:
public static void main(String[] args) { try { FileInputStream fileInputStream = new FileInputStream("Java01/text.txt"); FileOutputStream fileOutputStream = new FileOutputStream("Java01/newText.txt"); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");//InputStreamReader使用指定的 charset 读取字节并将其解码为字符。 OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); char input[] = new char[100]; int l = 0; while ((l = inputStreamReader.read(input)) != -1) { outputStreamWriter.write(input, 0, l); //将字符读入数组中的某一部分。 } // while (inputStreamReader.read(input) != -1) { //读入数组的的字符会存在偏移,即多读出字符 // outputStreamWriter.write(input); // } outputStreamWriter.close(); inputStreamReader.close(); fileOutputStream.close(); fileInputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
8. 使用带有缓冲的字符流读写数据
即添加BufferedReader和BufferedWriter,会出现一个问题,就是写入文件的时候会丢弃换行符,可使用PrintWriter
PrintWriter实例化:
PrintWriter pw = new PrintWriter(outputStreamWriter,true);//实例化并强制自动刷新缓冲区数据
9. FileReader与FileWriter
使用FileReader和FileWriter来读写一些纯文本文件,读写以字符为基准的文件。用法同上述几种文件读出方式类似,不做赘述。
10. RandomAccessFile随机文件读写
实例代码:
MultiwriterFile.java
package com.william.RandomAccessFileTest; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; /** * Created by william on 2016/11/25. */ public class MultiwriterFile { static File file = new File("Java01/text.txt"); public static void main(String[] args) { // if (file.exists()) { // file.delete(); // } // new WriteFile(file,1).start(); // new WriteFile(file,2).start(); // new WriteFile(file,3).start(); // new WriteFile(file,4).start(); // new WriteFile(file,5).start(); try { RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r"); randomAccessFile.seek(300); byte input[] = new byte[20]; randomAccessFile.read(input); String str = new String(input); System.out.print(str); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
WriteFile.java
package com.william.RandomAccessFileTest; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; /** * Created by william on 2016/11/25. */ public class WriteFile extends Thread { File file; int block; int L = 100; public WriteFile(File file, int block) { this.file = file; this.block = block; } /** * 文件随机读取示意图: * 1 2(100) 3 4(300) 5 * |-----------------|-----------------|-----------------|-----------------|-------- * 0xL<-----100----->1xL */ public void run() { try { RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); randomAccessFile.seek((block - 1) * L); randomAccessFile.writeBytes("This is block" + block); for (int i=0;i<20;i++) { randomAccessFile.writeBytes("-"); } randomAccessFile.writeBytes("\n"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
执行写操作,输出结果:
This is block1——————–
This is block2——————–
This is block3——————–
This is block4——————–
This is block5——————–
执行读操作输出结果:
输出:输出20个字节长度
This is block4——
11. 使用Apache IO库操作IO与文件
对原始java对文件的操作做了封装,使用起来更加的方便,详细请看Apache的官方API文档。
三. Java多线程编程
线程与进程线程:
程序中的单独顺序的控制流
新城本身依靠程序进行运行
线程是程序中的顺序控制流,只能使用分配给程序的资源和环境
进程:
执行中的程序
一个进程可以包含一个或多个线程
一个进程至少要包含一个线程
单线程:
程序中只存在一个线程,实际上主方法就是一个主线程
多线程:
多线程是在一个程序中运行多个任务
多线程的目的是更好的利用cpu资源
2. 线程的实现
在java中,线程的实现有两种:
①. 继承Thread类
②. 实现Runnable接口
Thread类:
Thread类是在java.lang包中定义的,继承Thread类必须重写run()方法
定义格式:
class className extends Thread{ run(){}; }
实例:
public class MyThread extends Thread { private String name; public MyThread(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println(name + ":" + i); } super.run(); } }
说明:当在主方法中使用Start启动线程时,我们可以看到两个线程时并行执行的,即谁先拿到cpu的资源,谁就执行,并不是顺序执行的。
看部分输出结果:
…
B:25
B:26
B:27
B:28
B:29
A:0
B:30
A:1
A:2
A:3
…
Runnable接口
实现Runnable接口中的run方法,与Thread的run方法一样,在主方法中调用时,如下调用:
MyRunnable r = new MyRunnable("A"); Thread t = new Thread(r); t.start();
3. 线程的状态
线程也有固定的操作状态:
创建状态:准备好了一个多线程的对象
就绪状态:调用了start()方法,等待cpu进行调度
运行状态:执行run()方法
阻塞状态:暂时停止执行,可能将资源交给其他线程使用
终止状态(死亡状态):线程销毁
4. 线程的常用方法
取得线程名称
getName()
取得当前线程对象
currentThread()
判断线程是否启动
isAlive()
线程的强行运行
join()
线程的休眠
sleep()
礼让
yield()
5. 线程的优先级
优先级顺序设置:
1-MIN_PRIORITY
10-MAX_PRIORITY
5-NORM_PRIORITY
如果什么都不设置默认值是5
6. 同步与死锁
同步代码块
在代码块上加上“synchronized”关键字,则此代码块就称为同步代码块
同步代码块格式:
synachronized(同步对象){
需要同步的代码块;
}
同步方法
除了代码块可以同步,方法也是可以同步的
方法同步格式:
synchronized void 方法名称(){}
同步实例:
class MyThreadDemo implements Runnable { private int ticket = 5; public void run() { for (int i = 0; i < 10; i++) { tell(); } } public synchronized void tell() { if (ticket > 0) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("车票:" + ticket--); } } } public class synchronizedtest { public static void main(String[] args) { MyThreadDemo m = new MyThreadDemo(); Thread t1 = new Thread(m); Thread t2 = new Thread(m); Thread t3 = new Thread(m); t1.start(); t2.start(); t3.start(); } }
而死锁,就相当与两个人耍赖皮,比如说:张三有十块钱,李四有一本书,张三说,你先把书给我,我就给你钱,李四说你先给我钱,我就给你书,两个人互不想让,就会陷入等待,就会出现死锁的状况。
7. 线程的生命周期
不解释,上图:
![](https://raw.githubusercontent.com/williamHappy/FileRepo/master/hexo/20161124/Java003/img/threadLife.png)
四. Java中的HTTP通信
使用Http的Get方法读取网络数据看下面博客吧,视频上讲的挺散,但是要感谢视频的老师,同时感谢博客的博主。:)
http://blog.csdn.net/luckyzhoustar/article/details/50259209
2. 使用Http的Post方式与网络交互通信
啥都不说了,还是博客文章:
http://blog.csdn.net/thl331860203/article/details/51783434
3. 使用HttpClient进行Get方式通信
使用Apache的HttpClient的jar包,具体的操作,自己网上查去吧,不像写了。
4. 使用HttpClient进行Post方式通信
使用Apache的HttpClient的jar包,具体的操作,自己网上查去吧,不像写了。
做参考吧:
https://www.oschina.net/code/snippet_1591393_46723
五. Java中内部类,匿名内部类理解
http://blog.csdn.net/zzjjiandan/article/details/9189943一般来说,有4种内部类:常规内部类、静态内部类、局部内部类、匿名内部类。
常规内部类
常规内部类和普通类最大的不同就是,它能访问(这里,访问的意思包括读和写)外部类的私有实例域。
具体参考博客:
http://blog.csdn.net/l294265421/article/details/46574009
静态内部类
静态内部类和普通类的对比使用,讲的很好,感谢博主:
http://kenby.iteye.com/blog/1603803
局部内部类
在局部内部类前不能用修饰符public和private,protected.
可以定义与外部类同名的变量
如果内部类没有与外部类同名的变量,在内部类中可以直接访问外部类的实例变量
如果内部类中有与外部类同名的变量,直接用变量名访问的是内部类的变量,用this.变量名访问的也是内部类变量.
用外部类名.this.内部类变量名访问的是外部类变量
不可以定义静态变量和方法
可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的
可以访问外部类的所有成员
实例:
http://blog.csdn.net/l294265421/article/details/46583475
匿名内部类
如果只需要创建一个内部类的一个对象,就没必要给这个类一个名字。这个没有名字的内部类叫做匿名内部类。
实例:
http://blog.csdn.net/l294265421/article/details/46583759
小插曲:关于类的实例化顺序
1.在实例化一个类的对象时,先要实例化该类的成员变量,再执行该类的构造函数。
2. 在实例化一个类的成员变量时,先要实例化静态成员变量,再实例化非静态成员变量。
3. 一个类的静态成员变量只实例化一次,即只有一个拷贝,在该类的所有对象中共享。
4. 执行一个类的静态成员函数时,该类的对象并没有生成,因此,只会实例化该类的静态成员变量,而不会实例化非静态成员变量,也不会执行构造函数。
最好自己写一个小的实例,然后自己debugger一下,这样更容易理解上述的总结,可以用下面的小实例:
class A{ private int a = 10; private static int AA = 100; public A(int a) { this.a = a; } public void printA(){ System.out.println("this is A"); } public static void printText(){ System.out.println("come here!"); } } public class newclasstest { public static void main(String[] args){ A.printText(); A a = new A(22); a.printA(); } }
相关文章推荐
- JAVA基础:提升JSP应用程序的七大绝招
- 提升JAVA程序的性能
- 提升Java性能的十一个用法
- JAVA数字签名提升权限
- Java高手:提升Java性能的十一个用法
- Java I/O性能提升
- 提升Java性能的十一个用法
- java 自动类型提升
- JAVA数字签名提升权限
- java中不同类型的转换和提升
- Java应用性能的提升
- Java中不同类型的转换和提升
- 提升ArcGIS Server for Java的REST访问切片图效率
- Java入门:java中不同类型的转换和提升
- 提升Java桌面客户端程序性能
- JAVA基础:提升JSP应用程序的七大绝招
- java 类型提升的约定
- 提升Java性能的一些方法
- 关于java applet引用第三方jar文件 applet权限的提升 通过网络访问
- java Applet 数字签证提升权限