您的位置:首页 > 编程语言 > Java开发

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)

比较ArrayListVector
推出时间JDK1.2之后推出JDK1.0推出
性能采用异步处理方式,性能高采用同步处理方式,性能低
线程安全属于非线程安全属于线程安全
Set接口

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)

“字符集”也称为“编码”。

三者的区别,请看下表:



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. 线程的生命周期

不解释,上图:



四. 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