Java集合

集合总图概览

Collection

Collection 分为List<E>接口和Set<E>接口。
共有的常见方法

添加:

boolean add(Object obj) //添加一个元素
boolean addAll(Collection all) //添加一个集合的元素

删除

boolean remove(Object obj) //删除一个元素
boolean removeAll(Collection all) //删除这个集合中有的元素在本集合中的元素

判断是否存在

boolean contains(Object obj) //判断该元素是否存在
boolean containsAll(Collection obj) //判断是否存在这个集合中所有的元素
boolean isEmpty() //判断是否为空

取交集

boolean retainAll(Collection coll) //取交集,保留和指定的集合相同的元素,而删除不同的元素。

其它

int size() //获取集合大小
Iterator iterator() //获取迭代器的首位置

迭代器使用

// it.next()代表it获取下一个元素,然后it再往前自增一位
for(Iterator it = coll.iterator(); it.hasNext(); ){System.out.println(it.next());
}

List<E>

List<E>接口一共有ArrayListLinkedListVector三个实现类。
ArrayList是数组,LinkedList是双向链表,Vector是同步的数组。
其共有的方法

添加

void add(int index, E element);
boolean addAll(int index, Collection<? extends E> c);

删除

E remove(int index);

修改

E set(int index, E element);

获取

E get(int index); //通过元素位置获取
int indexOf(Object o); //获取第一个该元素在集合中所在位置
int lastIndexOf(Object o); //获取最后一个该元素所在集合中位置
List<E> subList(int fromIndex, int toIndex); //获取[)区间的子List
Object[] toArray(); // 转换成数组

ListIterator<E>

ListIterator<E> listIterator(); //获取开头元素的iterator
ListIterator<E> listIterator(int index); //获取指定位置的iterator

ListIterator<E>使用

ListIterator it = list.listIterator();while(it.hasNext()){Object obj = it.next();// xxx 此处写你的业务代码
}// 逆序
while(it.hasPrevious()){Object obj = it.previous();// xxx 此处写你的业务代码
}

补充LinkedList一些独有的常用方法

LinkedList独有的方法

public void addFirst(E e) //插入元素在链表首位置
public void addLast(E e) //插入元素在链表尾部位置public E removeFirst() //移除链表头部元素
public E removeLast() //移除链表尾部元素public E getFirst() //获取队列中头部元素
public E getLast() //获取队列中尾部元素

补充,上述三种操作add、remove、get方法有对应的offer、poll、peek方法。其溢出、空、获取不到值等情况时返回null值而不抛出异常。

public void offerFirst(E e) //插入元素在链表首位置
public void offerLast(E e) //插入元素在链表尾部位置public E pollFirst() //移除链表头部元素
public E pollLast() //移除链表尾部元素public E peekFirst() //获取队列中头部元素
public E peekLast() //获取队列中尾部元素

Set<E>

Set用法与Collection一致。其中,HashSet底层是hash table。而TreeSet则是红黑树。

元素唯一性:通过对象的HashCodeequals方法实现的。
如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。

因此,我们如果要存自定义对象,则需要重写hashCode方法和equals方法

@Override
public int hashCode();@Override
public boolean equals(Object obj)

对于TreeSet,如果是自定义的类需要存储,则是需要实现Comparable接口,实现其中的Compareto方法。

    //return -1; //-1表示放在红黑树的左边,即逆序输出//return 1;  //1表示放在红黑树的右边,即顺序输出//return 0;  //表示元素相同,仅存放第一个元素@Overridepublic int compareTo(Student s)

Map<K, V>

Map<K, V>是Java开发的一个接口。其有两个实现类,一个是HashMap,一个是TreeMap。其中,HashMap底层为哈希表。通过key计算hash值,然后去对应位置找键值对。
TreeMap底层对于key来说,是用红黑树存储的。通过红黑树去查找key,比传统的遍历搜索快得多。但是又要慢于Hash方法。

常用方法:

增加

V put(K key, V value)

删除

V remove(Object key)
void clear() //清除所有键值对

查询

V get(Object key)

判断存在与否

boolean containsKey(Object key)  //存在这个key与否
boolean containsValue(Object value)  //存在这个value与否
boolean isEmpty() //map是否为空

遍历键值对需要准备

Set<Map.Entry<K, V>> entrySet() //遍历出所有的键值对,然后将他们存储到Set里面
Set<K> keySet() //获取所有键的Set
Collection<V> values() //获取所有value的set
int size()

遍历的例子

public class Test4 {public static void main(String[] args) {HashMap<Phone,String> map = new HashMap<>();map.put(new Phone("Apple",7000),"美国");map.put(new Phone("Sony",5000),"日本");map.put(new Phone("Huawei",6000),"中国");Set<Phone> phones = map.keySet();Iterator<Phone> iterator = phones.iterator();while (iterator.hasNext()){Phone next = iterator.next();System.out.println(next.getBrand()+"=="+next.getPrice()+"=="+map.get(next));}}
}//此处严谨一点,应该实现hashCode方法和equals方法。因为是自定义类做key。
class Phone{private String Brand;private int Price;public Phone(String brand, int price) {Brand = brand;Price = price;}public String getBrand() {return Brand;}public void setBrand(String brand) {Brand = brand;}public int getPrice() {return Price;}public void setPrice(int price) {Price = price;}
}//第二个遍历的例子
public class Test4 {public static void main(String[] args) {HashMap<Phone,String> map = new HashMap<>();map.put(new Phone("Apple",7000),"美国");map.put(new Phone("Sony",5000),"日本");map.put(new Phone("Huawei",6000),"中国");Set<Map.Entry<Phone, String>> entries = map.entrySet();for (Map.Entry<Phone, String> entry : entries) {System.out.println(entry.getKey().getBrand()+"==="+entry.getKey().getPrice()+"==="+entry.getValue());}}
}

Java IO

先上一张类图:

根据处理数据的不同分别为:字符流和字节流
根据数据流向不同分为:输入流和输出流

字符流和字节流

操作方式 字节流 字符流
读写单位 字节为单位 以字符为单位(一次可能读多字节)
处理对象 图片、文字、文档等所有类型数据 处理字符类型数据
一次读入读出 8bit 16bit

输入流:
InputStream 是所有的输入字节流的父类,它是一个抽象类。
ByteArrayInputStreamStringBufferInputStreamFileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。
PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。
ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)。

输出流:
OutputStream 是所有的输出字节流的父类,它是一个抽象类。
ByteArrayOutputStreamFileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。
PipedOutputStream 是向与其它线程共用的管道中写入数据。
ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。

节点流
节点流:直接与数据源相连,读入或读出。
直接使用节点流,读写不方便,为了更快的读写文件,才有了处理流。

父类:
InputStreamOutputStreamReaderWriter
文件:
FileInputStreamFileOutputStreamFileReaderFileWriter
数组:
ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter
字符串:
StringReaderStringWriter

处理流

缓冲流
BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter

转换流,实现字节流与字符流之间数据的转换
InputStreamReaderOutputStreamReader
其中,转换流需要InputStream或者OutputStream作为参数。实现从字符流到字节流的转换。

这两个类的构造:

public InputStreamReader(InputStream in);        //通过构造函数初始化,使用的是本系统默认的编码表GBK。
public InputStreamReader(InputStream in,String charSet);   //通过该构造函数初始化,可以指定编码表。
public OutputStreamWriter(OutputStream out);      //通过该构造函数初始化,使用的是本系统默认的编码表GBK。
public OutputStreamwriter(OutputStream out,String charSet);   //通过该构造函数初始化,可以指定编码表。

数据流,提供将基础数据类型写入到文件中,或者读取出来。
DataInputStreamDataOutputStream

File

File类型是对于文件进行操作的。其有六大构造函数

public File(String pathName); //指定绝对路径
public File(URI uri); //指定uri地址
public File(String parent, String child) //指定父文件绝对路径,子文件绝对路径
public File(File parent, String child) //指定父文件,子文件相对路径

还有两个私有构造函数,因为创建File类时候用不到,因此不在这里赘述了。

第一个构造函数的例子

String filePath1 = "D:/cat.png" ;
File file = new File( filePath1 ) ;

第三个构造函数例子

String parentFilePath = "E:/cat" ;
String childFilePath = "small_cat.txt" ;File parent = new File(parentFilePath);
parent.mkdir();//如果不存在父路径,就会抛出异常
File child = new File(parentFilePath, childFilePath);
try{child.createNewFile();
}catch(Exception e){e.printStackTrace();
}

第四个构造函数例子

String parentFilePath = "E:/cat" ;File parent = new File(parentFilePath);
parent.mkdir();//文件或者目录不存在就会抛出异常
File file = new File(parent, "xxx.txt");try{file.createNewFile();
}catch(IOException e){e.printStackTrace();
}

接下来是一些常用api:

public boolean mkdir(); //创建单级目录
public boolean mkdirs(); //创建多级目录
public boolean createNewFile();
public boolean exists() //文件是否存在
public boolean isFile() //是否是文件
public boolean isDirectory() //是否是目录
public boolean isHidden()   //是否隐藏(windows上可以设置某个文件是否隐藏)
public boolean isAbsolute() //是否为绝对路径
public boolean canRead()  //是否可读
public boolean canWrite() //是否可写
public boolean canExecute()  //是否可执行
public String getName() //获取文件的名字,只是名字,没有路径
public String getParent() //获取父目录的绝对路径,返回值是一个字符串。如果文件有父目录,那么返回父目录的绝对路径,(比如:`E:\cat`) , 如果文件本身就在磁盘的根目录,那么返回磁盘的路径,(比如:`E:\`)。
public File getParentFile() //获取父文件,返回值是一个File对象。
public long lastModified() ; //返回文件最后一次修改的时间
//上述返回值long可以直接用作Date实例的参数
//long time = file.lastModified();
//Date dt = new Date(time);
public boolean renameTo(File file) //文件命名
public long length() //返回文件的大小,单位字节
public boolean delete() //删除文件
public String[] list() //获取该目录下的所有的文件的名字。如果`file`为文件,返回值为`null`,在使用时记得判空;但是如果`file`为目录,那么返回这个目录下所有文件的名字,只是名字,不含路径;如果`file`是一个空目录,返回一个长度为0的数组;从上面的结果可以看出,`list()` 方法,只是对`file`为目录时有效,当`file`为一个文件的时候,该方法毫无意义。
public File[] listFiles() //获取该目录下的所有的文件。如果`file`为文件,返回值为`null`,在使用时记得判空;但是如果`file`为目录,那么返回这个目录下所有的文件 ;如果`file`是一个空目录,返回一个长度为0的数组;从上面的结果可以看出,`listFiles()` 方法,只是对`file`为目录时有效,当`file`为一个文件的时候,该方法毫无意义。

最后讲一下关于FileFilterFilenameFilter的问题

FileFilter
其作用是过滤自己所需要的文件。通过任何方式。需要重写里面的accept()方法

例子:只需要该目录下所有文件夹

package com.app;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;public class A3 {public static void main(String[] args) throws IOException {String filePath = "F:/" ;File file = new File( filePath ) ;getFile(file);}/*** 获取指定目录的所有文件夹* @param file*/private static void getFile( File file ){MyFileFilter myFileFilter = new MyFileFilter() ;File[] files = file.listFiles( myFileFilter ) ;for( File f : files ){if ( f.isHidden() ) continue ;System.out.println( f.getAbsolutePath() );}}static class MyFileFilter implements FileFilter {MyFileFilter(){}//pathname:文件的绝对路径+ 文件名 , 比如:F:\安来宁 - 难得.mp3  , 或者: F:\文件夹1@Overridepublic boolean accept(File pathname) {if( pathname.isDirectory() ){return true ;}return false;}}
}

FilenameFilter
一样的,重写accept()方法。这是通过名字过滤。

package com.app;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;public class A3 {public static void main(String[] args) throws IOException {String filePath = "F:/" ;File file = new File( filePath ) ;getFile(file);}/*** 扫描出指定路径的所有图片* @param file*/private static void getFile( File file ){MyFilenameFilter myFileFilter = new MyFilenameFilter( ".png") ;File[] files = file.listFiles( myFileFilter ) ;for( File f : files ){if ( f.isHidden() ) continue ;System.out.println( f.getAbsolutePath() );}}static class MyFilenameFilter implements FilenameFilter {//type为需要过滤的条件,比如如果type=".jpg",则只能返回后缀为jpg的文件private String type;           MyFilenameFilter( String type){this.type = type ;}@Overridepublic boolean accept(File dir, String name) {//dir表示文件的当前目录,name表示文件名;return name.endsWith( type ) ;}}
}

缓冲流

缓冲流分为InputStreamOutputStream这两种流。其中,这两种流又有其各自的子类,分别为BufferedInputStreamBufferedOutputStream这两种。这两种是用来封装对应的节点流的。因为直接操作节点流会对磁盘IO产生很大的影响。因此,我们需要一个缓冲区来对节点流进行封装,让磁盘IO次数减少。

BufferedInputStream

BufferedInputStream 的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持mark()标记和reset()重置方法。

BufferedInputStream 本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

BufferedInputstream常用Api

类具有的字段:

private static int defaultBufferSize = 8192;//内置缓存字节数组的大小 8KB
protected volatile byte buf[]; //内置缓存字节数组
protected int count;    //当前buf中的字节总数、注意不是底层字节输入流的源中字节总数
protected int pos;      //当前buf中下一个被读取的字节下标
protected int markpos = -1;    //最后一次调用mark(int readLimit)方法记录的buf中下一个被读取的字节的位置
protected int marklimit;    //调用mark后、在后续调用reset()方法失败之前云寻的从in中读取的最大数据量、用于限制被标记后buffer的最大值

构造函数:

BufferedInputStream(InputStream in) //使用默认buf大小、底层字节输入流构建bis
BufferedInputStream(InputStream in, int size) //使用指定buf大小、底层字节输入流构建bis

常用api:

int available();  //返回底层流对应的源中有效可供读取的字节数
void close();  //关闭此流、释放与此流有关的所有资源
boolean markSupport();  //查看此流是否支持mark
void mark(int readLimit); //标记当前buf中读取下一个字节的下标
int read();  //读取buf中下一个字节
int read(byte[] b, int off, int len);  //读取buf中下一批字节数据
void reset();   //重置最后一次调用mark标记的buf中的位子
long skip(long n);  //跳过n个字节、 不仅仅是buf中的有效字节、也包括in的源中的字节

BufferedOutputStream

BufferedOutputStream是用作输出缓冲作用所用的一种流,我们在用完它之后需要关闭这个流对象。所以要注意在使用BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。否则可能无法写出数据。

常用api:

protected byte[] buf;   //内置缓存字节数组、用于存放程序要写入out的字节
protected int count;   //内置缓存字节数组中现有字节总数

构造函数:

BufferedOutputStream(OutputStream out); //使用默认大小、底层字节输出流构造bos。默认缓冲大小是 8192 字节( 8KB )
BufferedOutputStream(OutputStream out, int size);  //使用指定大小、底层字节输出流构造bos

常用方法及close()方法

//在这里提一句,`BufferedOutputStream`没有自己的`close`方法,当他调用父类`FilterOutputStrem`的方法关闭时,会间接调用自己实现的`flush`方法将buf中残存的字节flush到out中,再`out.flush()`到目的地中,DataOutputStream也是如此。
void  flush();  //将写入bos中的数据flush到out指定的目的地中、注意这里不是flush到out中、因为其内部又调用了out.flush()
write(byte b);      //将一个字节写入到buf中
write(byte[] b, int off, int len);      //将b的一部分写入buf中

BufferedOutputStream在调用close()时,会一同调用flush()方法。因此为什么要在try-catch-finally代码块调用close(),就是确保数据不要因为没有输出到文件、内存而被JVM清理了。

调用BufferedOutputStreamclose()方法时,也会关闭OutputStream流。因为在close()方法中,调用了flush()方法。因此就会关闭并且将在缓冲区的数据刷写出输出流。

因此,在关闭处理流时,节点流也一同关闭了。

例子:

public class A3 {public static void main(String[] args) throws IOException {String filePath = "F:/123.png" ;String filePath2 = "F:/abc.png" ;File file = new File( filePath ) ;File file2 = new File( filePath2 ) ;copyFile( file , file2 );}/*** 复制文件* @param oldFile* @param newFile*/public static void copyFile( File oldFile , File newFile){InputStream inputStream = null ;BufferedInputStream bufferedInputStream = null ;OutputStream outputStream = null ;BufferedOutputStream bufferedOutputStream = null ;try {inputStream = new FileInputStream( oldFile ) ;bufferedInputStream = new BufferedInputStream( inputStream ) ;outputStream = new FileOutputStream( newFile ) ;bufferedOutputStream = new BufferedOutputStream( outputStream ) ;byte[] b=new byte[1024];   //代表一次最多读取1KB的内容int length = 0 ; //代表实际读取的字节数while( (length = bufferedInputStream.read( b ) )!= -1 ){//length 代表实际读取的字节数bufferedOutputStream.write(b, 0, length );}//缓冲区的内容写入到文件bufferedOutputStream.flush();} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}finally {if( bufferedOutputStream != null ){try {bufferedOutputStream.close();} catch (IOException e) {e.printStackTrace();}}if( bufferedInputStream != null){try {bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}}if( inputStream != null ){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if ( outputStream != null ) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}
}

reader 与 writer类字符流

类的继承关系

Reader

|__ BufferedReader、StringReader、InputStreamReader|__ FileReader

Writer

|__ BufferedWriter、StringWriter、OutputStreamWriter|__ FileWriter

BufferedReader

构造函数

BufferedReader(Reader in, int sz) //创建一个使用指定大小输入缓冲区的缓冲字符输入流。 BufferedReader(Reader in) //创建一个使用默认大小输入缓冲区的缓冲字符输入流。

方法

int  read()  //读取单个字符。
int  read(char[] cbuf, int off, int len)  //将字符读入数组的某一部分。
String  readLine()  //读取一个文本行。
boolean  ready()  //判断此流是否已准备好被读取。
void  reset()  //将流重置到最新的标记。
long  skip(long n)  //跳过字符。
void  close() //关闭该流并释放与之关联的所有资源。
void  mark(int readAheadLimit) //标记流中的当前位置。
boolean  markSupported() //判断此流是否支持 mark() 操作(它一定支持)。

BufferedWriter

构造函数

BufferedWriter(Writer out, int sz) //创建一个使用给定大小输出缓冲区的新缓冲字符输出流。BufferedWriter(Writer out) //建一个使用默认大小输出缓冲区的缓冲字符输出流。

方法

void  close()  // 关闭此流,但要先刷新它。
void  flush()  //刷新该流的缓冲。
void  newLine() //写入一个行分隔符。
void  write(char[] cbuf, int off, int len) //写入字符数组的某一部分。
void  write(int c) //写入单个字符。
void  write(String s, int off, int len) //写入字符串的某一部分。

总体例子:

public class A4 {public static void main(String[] args) {String filePath = "F:/123.txt" ;String filePath2 = "F:/abc.txt" ;File file = new File( filePath ) ;File file2 = new File( filePath2 ) ;copyFile( file , file2 );}private static void copyFile( File oldFile , File newFile ){Reader reader = null ;BufferedReader bufferedReader = null ;Writer writer = null ;BufferedWriter bufferedWriter  = null ;try {reader = new FileReader( oldFile ) ;bufferedReader = new BufferedReader( reader ) ;writer = new FileWriter( newFile ) ;bufferedWriter = new BufferedWriter( writer ) ;String result = null ; //每次读取一行的内容while (  (result = bufferedReader.readLine() ) != null ){bufferedWriter.write( result );  //把内容写入文件bufferedWriter.newLine();  //换行,result 是一行数据,所以没写一行就要换行 }bufferedWriter.flush();  //强制把数组内容写入文件} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}finally {try {bufferedWriter.close();  //关闭输出流} catch (IOException e) {e.printStackTrace();}}}
}

InputStreamReader 和 OutputStreamReader转换流

这两个流可以从字节向字符的转变。因此,我们可以用其进行包装一些字节流。同时这两个流可以被缓冲流所包装,对其进行缓冲。

类的继承关系

Reader
|__ BufferedReader、StringReader、InputStreamReader|__ FileReader
Writer
|__ BufferedWriter、StringWriter、OutputStreamWriter|__ FileWriter

InputStreamReader简介
InputStreamReader 是字符流Reader的子类,是字节流通向字符流的桥梁。你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如 GBK 等。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。一次只读一个字符。

InputStreamReader构造函数

InputStreamReader(Inputstream  in) //创建一个使用默认字符集的 InputStreamReader。InputStreamReader(Inputstream  in,Charset cs) //创建使用给定字符集的 InputStreamReader。InputStreamReader(InputStream in, CharsetDecoder dec) //创建使用给定字符集解码器的 InputStreamReader。InputStreamReader(InputStream in, String charsetName)  //创建使用指定字符集的 InputStreamReader。

一般方法

void  close() // 关闭该流并释放与之关联的所有资源。String getEncoding() //返回此流使用的字符编码的名称。int   read()  //读取单个字符。int    read(char[] cbuf, int offset, int length) //将字符读入数组中的某一部分。boolean  ready() //判断此流是否已经准备好用于读取。

OutputStreamWriter简介
OutputStreamWriter 是字符流Writer的子类,是字符流通向字节流的桥梁。每次调用 write()方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。一次只写一个字符。

OutputStreamWriter构造函数

OutputStreamWriter(OutputStream out) //创建使用默认字符编码的 OutputStreamWriterOutputStreamWriter(OutputStream out, String charsetName) //创建使用指定字符集的 OutputStreamWriter。OutputStreamWriter(OutputStream out, Charset cs) //创建使用给定字符集的 OutputStreamWriter。OutputStreamWriter(OutputStream out, CharsetEncoder enc) //创建使用给定字符集编码器的 OutputStreamWriter。

一般方法

void  write(int c)   //写入的字符长度void  write(char cbuf[])  //写入的字符数组void  write(String str)  //写入的字符串void  write(String str, int off, int len)  //应该写入的字符串,开始写入的索引位置,写入的长度void  close() //关闭该流并释放与之关联的所有资源。

需要注意的事项

InputStreamReaderOutputStreamWriter实现从字节流到字符流之间的转换,使得流的处理效率得到提升,但是如果我们想要达到最大的效率,我们应该考虑使用缓冲字符流包装转换流的思路来解决问题。比如:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

实例:

public class A5 {public static void main(String[] args) {String filePath = "F:/123.txt" ;String filePath2 = "F:/abc.txt" ;File file = new File( filePath ) ;File file2 = new File( filePath2 ) ;copyFile( file , file2 );}private static void copyFile( File oldFile , File newFile ){InputStream inputStream = null ;InputStreamReader inputStreamReader = null ;OutputStream outputStream = null ;OutputStreamWriter outputStreamWriter = null ;try {inputStream = new FileInputStream( oldFile ) ; //创建输入流inputStreamReader = new InputStreamReader( inputStream ) ; //创建转换输入流outputStream = new FileOutputStream( newFile ) ; //创建输出流outputStreamWriter = new OutputStreamWriter( outputStream ) ; //创建转换输出流int result = 0 ;while( (result = inputStreamReader.read()) != -1){  //一次只读一个字符outputStreamWriter.write( result ); //一次只写一个字符}outputStreamWriter.flush();  //强制把缓冲写入文件} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}finally{if ( outputStreamWriter != null) {try {outputStreamWriter.close();} catch (IOException e) {e.printStackTrace();}}if ( inputStreamReader != null ) {try {inputStreamReader.close();} catch (IOException e) {e.printStackTrace();}}}}
}

ByteArrayInputStream、ByteArrayOutputStream

这两个流是用来将字节数组和输入输出流互相转化的。
其中,ByteArrayInputStream是用来将字节数组转化为输入流。ByteArrayOutputStream是用来将内存缓冲区转化为字节数组输出。

ByteArrayInputStream

构造函数:

public ByteArrayInputStream(byte buf[])public ByteArrayInputStream(byte buf[], int offset, int length)

一般方法

void  close() // 关闭该流并释放与之关联的所有资源。String getEncoding() //返回此流使用的字符编码的名称。int   read()  //读取单个字符。int    read(char[] cbuf, int offset, int length) //将字符读入数组中的某一部分。boolean  ready() //判断此流是否已经准备好用于读取。

关于简化文件的一些操作,Apache基金会发布了FileUtils这个工具类。因此,我们可以使用这个工具类,简化我们对文件的crud。

其maven导入:

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.8.0</version>
</dependency>

具体用法参见:
FileUtils的一些用法,链接到别人博客

多线程

由于篇幅过大,多线程移步这一个博客"Java多线程"

Java集合、IO、多线程的一些知识相关推荐

  1. java中IO流的相关知识

    目录 一.背景 二.IO流的分类 三.字符流操作相关代码示例 1.FileReader读取文件内容 2.FileWriter向文件写数据 3.实现文件内容复制 4.注意事项 5.利用try-catch ...

  2. [F2F] Java基础 (JDK特性/集合/IO/锁)

    简介 Java基础包含:JDK特性,集合, IO, 多线程 / 锁,JVM / JVM调优 等几大类, 单篇幅限制本文主要为 JDK特性,集合, IO,其他为链接到另一篇文章 多线程 / 线程池

  3. BeginnersBook Java 集合教程

    来源:ApacheCN BeginnersBook 翻译项目 译者:飞龙 协议:CC BY-NC-SA 4.0 贡献指南 本项目需要校对,欢迎大家提交 Pull Request. 请您勇敢地去翻译和改 ...

  4. Java基础巩固(二)异常,多线程,线程池,IO流,Properties集合,IO工具类,字符流,对象流,Stream,Lambda表达式

    一.异常,多线程 学习目标 : 异常的概述 异常的分类 异常的处理方式 自定义异常 多线程入门 1 异常的概述 1.1 什么是异常? 异常就是程序出现了不正常情况 , 程序在执行过程中 , 数据导致程 ...

  5. Java基础、多线程、JVM、集合八股文自述(持续更新)

    Java基础.多线程.JVM.集合八股文自述 一.Java基础 1.1 object类有哪些方法? getClass().hashCode().equals().clone().toString(). ...

  6. Java核心技术基础知识学习之Java集合(三)

    文章目录 七.Java集合 7.6 Java 8 增强的 Map 集合 7.6.1 Java 8 中 Map 新增的方法 7.6.2 Java 8 改进的 HashMap 和 HashTable 实现 ...

  7. Java集合知识概括

    Java集合知识概括 集合框架概述 Collection方法 Iterator迭代器接口 Collection子接口一:List Collection子接口二:Set Map接口 Collection ...

  8. Java集合框架的知识总结(1)

    Java集合框架的知识总结(1) 所有集合类都位于java.util包下.集合中只能保存对象(保存对象的引用变量). Java的集合类主要由两个接口派生而出:Collection和Map,Collec ...

  9. Java学习笔记(7)——Java基础之IO多线程网络思维导图

    Java面向对象学习笔记之:包括IO(字节流,字符流,节点流,处理流).线程(线程创建,线程控制,线程同步).网络(TCP Scoket,  UDP Scoket)(全屏观看Java学习笔记(7)-- ...

最新文章

  1. Codeforces 862B - Mahmoud and Ehab and the bipartiteness
  2. 百度宣布:搜索业务总裁向海龙离职,另回购10亿美元股份
  3. LeetCode--485
  4. 经济学人: 低调应用, 高调回报, 亚马逊才是AI技术最大受益企业
  5. 《C++ primer》--第三章
  6. centos 6.8 安装telnet-server服务
  7. 字节跳动面试题:用归并排序判断冒泡排序的轮数
  8. android标题 折叠效果,Android TextView仿微信可折叠效果
  9. Jmeter之线程组详解
  10. Eclipse安装Database Development插件。
  11. mysql 帮助命令_一篇文章帮你搞定所有MySQL命令!
  12. 玩转mini2440开发板之【编译u-boot提示没有规则可以创建“XX.o”需要的目标】
  13. atheros蓝牙设备驱动 小米_小米Air 13笔记本黑苹果WiFi蓝牙硬件改装方案二
  14. js layui 弹出子窗体_layui 弹出界面弹框
  15. 山西省计算机商务学校地址,山西计算机等级考试报名地点
  16. 飞思卡尔单片机c语言编程详解,飞思卡尔单片机PIT汇编编程(一)
  17. 五个角度浅析大数据与BI的区别
  18. 互联网没有基业长青?(转)
  19. EKL日志分析平台-kibana数据可视化
  20. CRMEB小程序商城源码安装后,个人中心推广海报不显示处理方法!

热门文章

  1. 神经网络入门经典书籍,神经网络的书籍推荐
  2. 速营社团队分享互联网发展过程那些疯狂的时代
  3. Unity教程:URP渲染管线实战教程系列【1】
  4. sideeffects没配置css也还在,webpack4踩坑配置之sideEffects, 打包文件中没有css文件
  5. Raspbian镜像无头烧录
  6. centos7建站操作步骤
  7. 判断小米 魅族 华为 系统 MIUI EMUI FLYME
  8. 远程监控Wifi与4G蜂窝流量连接有什么不同
  9. java计算机毕业设计志愿者管理系统演示录像2020源码+mysql数据库+系统+lw文档+部署
  10. LLVM | 编译器框架