Map:一次添加一对元素。Collection 一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实map集合中存储的就是键值对。 map集合中必须保证键的唯一性。
常用方法:
1,添加。
value put(key,value):返回前一个和key关联的值,如果没有返回null.
2,删除。
void clear():清空map集合。
value remove(key):根据指定的key翻出这个键值对。
3,判断。
boolean containsKey(key):
boolean containsValue(value):
boolean isEmpty();
4,获取。
value get(key):通过键获取值,如果没有该键返回null。
当然可以通过返回null,来判断是否包含指定键。
int size(): 获取键值对的个数。
Map常用的子类:
|--Hashtable :内部结构是哈希表,是同步的。不允许null作为键,null作为值。
|--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
|--HashMap : 内部结构是哈希表,不是同步的。允许null作为键,null作为值。
|--TreeMap : 内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。
练习:
<span style="font-size:14px;">package 面试题;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
//练习:
/*“adjankjdaopkdldmd”获取该字符串中字母出现的次数*/
public class MapText {
public static void main(String[] args) {
String str = "adjankjdaopkdldmd";
String s = show(str);
System.out.print(s);
}
public static String show(String str) {
//将字符串变成字符数组
char[] c = str.toCharArray();
//定义map集合
Map<Character, Integer > me = new TreeMap<Character,Integer >();
for(int i = 0; i < c.length; i ++ ){
int count = 0;
Integer value = me.get(c[i]);
if(value != null)
count = value;
count ++;
me.put(c[i], count);
}
return myToString(me);
}
private static String myToString(Map<Character, Integer> me) {
// TODO 自动生成的方法存根
StringBuilder sb = new StringBuilder();
Iterator<Character> i = me.keySet().iterator();
while(i.hasNext()){
Character key = i.next();
Integer value = me.get(key);
sb.append(key + "("+value+")");
}
return sb.toString();
}
}
</span>
运行结果
<span style="font-size:14px;">a(3)d(5)j(2)k(2)l(1)m(1)n(1)o(1)p(1)</span>
foreach语句:
格式:
for(类型 变量 :Collection集合|数组)
{
}
传统for和高级for的区别?
传统for可以完成对语句执行很多次,因为可以定义控制循环的增量和条件。
高级for是一种简化形式。
它必须有被遍历的目标。该目标要是数组,要么是Collection单列集合。
对数数组的遍历如果仅仅是获取数组中的元素,可以使用高级for。如果要对数组的角标进行操作建议使用传统for。
IO流
输入流和输出流相对于内存设备而言.
将外设中的数据读取到内存中:输入
将内存的数写入到外设中:输出。
字符流的由来:
其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表。获取对应的文字。
在对这个文字进行操作。简单说:字节流+编码表
字节流的两个顶层父类:
1,InputStream 2,OutputStream.
字符流的两个顶层父类:
1,Reader 2,Writer
这些体系的子类都以父类名作为后缀。 而且子类名的前缀就是该对象的功能。
装饰设计模式:对一组对象的功能进行增强时,就可以使用该模式进行问题的解决。
装饰比继承更灵活。装饰类和被装饰类都必须所属同一个接口或者父类。
为了方便字符和字节之间的转换操作,IO流中有两个转换流:
InputStreamReader 字节流通向字符流的桥梁
OutputStreamWriter 字符流通向字节流的桥梁
为了提高字符的读写效率,IO流中有两个对象BufferedReader和BufferedWriter字符缓冲流。
BufferedReader和BufferedWriter演示。
<span style="font-size:14px;">package iodemo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* 需求:在控制台打印数据,转换成大写输出,“over”结束。
* @author Administrator
*
*/
public class BufferedReaderBufferedWriterDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
show();
}
public static void show() throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String s;
while((s = br.readLine())!=null)
{
if(s.equals("over"))
break;
bw.write(s.toUpperCase());
bw.newLine();
bw.flush();
}
}
}</span>
IO流的操作规律总结:
1,明确体系:
数据源:InputStream ,Reader
数据汇:OutputStream,Writer
2,明确数据:因为数据分两种:字节,字符。
数据源:是否是纯文本数据呢?是:Reader 否:InputStream
数据汇:是:Writer 否:OutputStream
到这里就可以明确具体要使用哪一个体系了。剩下的就是要明确使用这个体系中的哪个对象。
3,明确设备:
数据源:键盘:System.in硬盘:File内存:数组。网络:socket socket.getInputStream();
数据汇:控制台:System.out硬盘:File内存:数组网络:socket socket.getOutputStream();
4,明确额外功能:
1,需要转换?是,使用转换流。InputStreamReader OutputStreamWriter
2,需要高效?是,使用缓冲区。Buffered
3,需要其他?
1,复制一个文本文件。
1,明确体系:
源:InputStream ,Reader
目的:OutputStream ,Writer
2,明确数据:
源:是纯文本吗?是 Reader
目的;是纯文本吗?是 Writer
3,明确设备:
源:硬盘上的一个文件。 FileReader
目的:硬盘上的一个文件。FileWriter
FileReader fr = new FileReader("a.txt"); FileWriterfw= new FileWriter("b.txt");
4,需要额外功能吗?
需要,高效,使用buffer
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
2,读取键盘录入,将数据存储到一个文件中。
1,明确体系:
源:InputStream ,Reader
目的:OutputStream ,Writer
2,明确数据:
源:是纯文本吗?是 Reader
目的;是纯文本吗?是 Writer 3,明确设备:
源:键盘,System.in 目的:硬盘,FileWriter
InputStream in = System.in;
FileWriter fw = new FileWriter("a.txt");
4,需要额外功能吗?
需要,因为源明确的体系时Reader。可是源的设备是System.in。 所以为了方便于操作文本数据,将源转成字符流。需要转换流。
InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("a.txt");
需要高效不?需要。Buffer
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("a.txt"));
3,读取一个文本文件,将数据展现在控制台上。
1,明确体系:
源:InputStream ,Reader
目的:OutputStream ,Writer
2,明确数据:
源:是纯文本吗?是 Reader
目的;是纯文本吗?是 Writer
3,明确设备:
源:硬盘文件,FileReader。
目的:控制台:System.out。
FileReader fr = new FileReader("a.txt"); OutputStream out = System.out;
4,需要额外功能?
因为源是文本数据,确定是Writer体系。所以为了方便操作字符数据,
需要使用字符流,但是目的又是一个字节输出流。
需要一个转换流,OutputStreamWriter
FileReader fr = new FileReader("a.txt");
OutputStreamWriter osw = new OutputStreamWriter(System.out);
需要高效吗?需要。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
4,读取键盘录入,将数据展现在控制台上。
1,明确体系:
源:InputStream ,Reader
目的:OutputStream ,Writer
2,明确数据:
源:是纯文本吗?是 Reader
目的;是纯文本吗?是 Writer 3,明确设备:
源:键盘:System.in 目的:控制台:System.out
InputStream in = System.in; OutputStream out = System.out;
4,需要额外功能吗?
因为处理的数据是文本数据,同时确定是字符流体系。
为方便操作字符数据的可以将源和目的都转成字符流。使用转换流。 为了提高效率,使用Buffer
BufferedReader bufr =new BufferedReader(newInputStreamReader(Systme.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
5,读取一个文本文件,将文件按照指定的编码表UTF-8进行存储,保存到另一个文件中。
1,明确体系:
源:InputStream ,Reader
目的:OutputStream ,Writer
2,明确数据:
源:是纯文本吗?是 Reader
目的;是纯文本吗?是 Writer
3,明确设备:
源:硬盘:FileReader.
目的:硬盘:FileWriter
FileReader fr = new FileReader("a.txt"); FileWriter fw =new FileWriter("b.txt");
4,额外功能:
注意:目的中虽然是一个文件,但是需要指定编码表。
而直接操作文本文件的FileWriter本身内置的是本地默认码表。无法明确具体指定码表。
这时就需要转换功能。OutputStreamWriter,而这个转换流需要接受一个字节输出流,而且对应的目的是一个文件。这时就使用字节输出流中的操作文件的流对象。FileOutputStream.
FileReader fr = new FileReader("a.txt");
OutputStreamWriter osw = new OutputStreamWriter(newFileOutputStream("b.txt"),"UTF-8");
需要高效吗?
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8"));
目前为止,10个流对象重点掌握。
字符流:
FileReader FileWriter
BufferedReader BufferedWriter
InputStreamReader OutputStreamWrier
字节流:
FileInputStream FileOutputStream
BufferedInputStreamBufferedOutputStream
File类:
用于将文件和文件夹封装成对象。
1,创建。
boolean createNewFile();如果该文件不存在,会创建,如果已存在,则不创建。不会像输出流一样会覆盖。
boolean mkdir(); boolean mkdirs();创建文件和创建多重文件夹
2,删除。
boolean delete();void deleteOnExit();
3,获取:
String getAbsolutePath();String getPath();
String getParent();
String getName();longlength();
long lastModified();
4,判断:
boolean exists();boolean isFile(); boolean isDirectory();
IO中的其他功能流对象:
1,打印流:
PrintStream:字节打印流。
特点:
1,构造函数接收File对象,字符串路径,字节输出流。意味着打印目的可以有很多。
2,该对象具备特有的方法 打印方法 print println,可以打印任何类型的数据。
3,特有的print方法可以保持任意类型数据表现形式的原样性,将数据输出到目的地。
对于OutputStream父类中的write,是将数据的最低字节写出去。
PrintWriter:字符打印流。 特点:
1,当操作的数据是字符时,可以选择PrintWriter,比PrintStream要方便。
2,它的构造函数可以接收 File对象,字符串路径,字节输出流,字符输出流。
3,构造函数中,如果参数是输出流,那么可以通过指定另一个参数true完成自动刷新,该true对
println方法有效。
什么时候用?当需要保证数据表现的原样性时,就可以使用打印流的打印方法来完成,这样更为方便。保证原样性的原理:其实就是将数据变成字符串,在进行写入操作。
SequenceInputStream:
特点:
1,将多个字节读取流和并成一个读取流,将多个源合并成一个源,操作起来方便。
2,需要的枚举接口可以通过Collections.enumeration(collection);
ObjectInputStream 和 ObjectOutputStream
对象的序列化和反序列化。
writeObject readObject
Serializable标记接口
关键字:transient:非静态数据不想使用序列化,可使用该关键字。
RandomAccessFile:
特点:
1,即可读取,又可以写入。
2,内部维护了一个大型的byte数组,通过对数组的操作完成读取和写入。
3,通过getFilePointer方法获取指针的位置,还可以通过seek方法设置指针的位置。
4,该对象的内容应该封装了字节输入流和字节输出流。
5,该对象只能操作文件。
通过seek方法操作指针,可以从这个数组中的任意位置上进行读和写 可以完成对数据的修改。
但是要注意:数据必须有规律。
管道流:需要和多线程技术相结合的流对象。PipedOutputStreamPipedInputStream
用操作基本数据类型值的对象: DataInputStreamDataOutputStream
设备是内存的流对象。
ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
IO流体系:
字符流:
Reader
|--BufferedReader:
|--LineNumberReader
|--CharArrayReader
|--StringReader
|--InputStreamReaer
|--FileReade
Writer
|--BufferedWriter
|--CharArrayWriter
|--StringWriter
|--OutputStreamWriter
|--FileWriter
|--PrintWriter
字节流:
InputStream
|--FileInputStream:
|--FilterInputStream
|--BufferedInputStream
|--DataInputStream
|--ByteArrayInputStream
|--ObjectInputStream
|--SequenceInputStream
|--PipedInputStream
OutputStream
|--FileOutputStream
|--FilterOutputStream
|--BufferedOutputStream
|--DataOutputStream
|--ByteArrayOutputStream
|--ObjectOutputStream
|--PipedOutputStream
|--PrintStream
练习复制文件:
package iodemo;
/**
*演示复制文件
*/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyMusic {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
copy3();
}
private static void copy1() throws IOException {
// TODO Auto-generated method stub
FileInputStream fi = new FileInputStream("c:\\陶喆 - 寂寞的季节.ape");
FileOutputStream fo = new FileOutputStream("d:\\陶喆 - 寂寞的季节.ape");
byte[] buf = new byte[10240];
int len = 0;
while((len = fi.read(buf))!=-1){
fo.write(buf, 0, len);
}
fi.close();
fo.close();
}
private static void copy2() throws IOException {
// TODO Auto-generated method stub
FileInputStream fi = new FileInputStream("c:\\陶喆 - 寂寞的季节.ape");
BufferedInputStream bi =new BufferedInputStream(fi);
FileOutputStream fo = new FileOutputStream("d:\\陶喆 - 寂寞的季节.ape");
BufferedOutputStream bo =new BufferedOutputStream(fo);
int len = 0;
while((len = bi.read())!=-1){
bo.write(len);
}
bi.close();
bo.close();
}
private static void copy3() throws IOException {
// TODO Auto-generated method stub
FileInputStream fi = new FileInputStream("c:\\陶喆 - 寂寞的季节.ape");
FileOutputStream fo = new FileOutputStream("d:\\陶喆 - 寂寞的季节.ape");
byte[] buf = new byte[fi.available()];
fi.read(buf);
fo.write(buf);
fi.close();
fo.close();
}
}
练习:深度遍历
package iodemo;
import java.io.File;
/**
* 深度遍历
* 需求:对指定的目录进行所有内容列出(包含子目录内容)
* @author mc
*
*/
public class Text2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
File files = new File("d:\\java") ;
listAll(files,0);
}
public static void listAll(File files, int level) {
// TODO Auto-generated method stub
level ++;
System.out.println(getSpace(level)+"文件夹:"+files.getAbsolutePath());
File[] f = files.listFiles();
for(int x = 0; x < f.length; x ++)
{
if(f[x].isDirectory())
listAll(f[x],level);
else
System.out.println(getSpace(level)+"文件"+f[x].getAbsolutePath());
}
}
private static String getSpace(int level) {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
for(int i = 0;i < level; i ++)
sb.append("--");
return sb.toString();
}
}
练习:使用次数
package iodemo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/**
* 需求:定义一个功能,记录一个程序的使用次数,如果超过五次,则给出使用次数已到请注册,并不再运行应用程序
*
* 思路:
* 1、记录数据用到计数器,定义一个计数器,每用一次,计数器加一
* 2、计数器要持久保存,当内存结束时,使用次数仍然记录在硬盘中。
* 3、记录次数要声明,方便阅读,就用到了map集合,又要操作硬盘数据,用到IO流
* map + IO = properties
* @author mc
*
*/
public class Text3 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
show();
}
public static void show() throws IOException {
// TODO Auto-generated method stub
//创建配置文件,并封装成对象
File conFile = new File("count.properties");
//判断文件是否存在
if(!conFile.exists())
conFile.createNewFile();
//创建输入流读取配置文件
FileInputStream is = new FileInputStream(conFile);
//创建集合properties,记录使用次数
Properties pp = new Properties();
pp.load(is);
String value = pp.getProperty("time");
//定义计数器
int count = 0;
if(value!=null){
count = Integer.parseInt(value);
if(count > 5)
throw new Error("使用次数已达上线,请注册后再使用");
}
count ++;
//将键值添加到集合中去
pp.setProperty("time", count+"");
//将集合内容传到配置文件中
FileOutputStream fos = new FileOutputStream(conFile);
pp.store(fos, "properties");
is.close();
fos.close();
}
}
练习:创建文件切割器
package 复习;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
/**
* 创建一个文件切割器;
* @author Administrator
*
*/
public class SplitFileDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File file = new File("D:\\陶喆 - 寂寞的季节.ape");
File dir = new File("G:\\陶喆 - 寂寞的季节");
if(!dir.exists())
dir.mkdirs();
splitFile(file, dir );
File f1 = new File("G:\\");
File d1 = new File("G:\\陶喆 - 寂寞的季节");
mergeFile(f1,d1);
}
public static void splitFile(File file, File dir) throws IOException {
// TODO Auto-generated method stub
//输入流读取源文件
FileInputStream fis = new FileInputStream(file);
byte[] buf = new byte[1024*1024*5];
int len = 0;
int count = 1;
//创建输出流,获取数据
FileOutputStream fos = null;
while((len = fis.read(buf)) != -1){
fos = new FileOutputStream(new File(dir,(count++) + ".part"));
fos.write(buf, 0, len);
fos.close();
}
//创建配置文件,用于合并时使用
Properties prop = new Properties();
prop.setProperty("filecount", count+"");
prop.setProperty("filename", file.getName());
fos = new FileOutputStream(new File(dir,count + ".properties"));
//将Properties中的信息持久性的储存到文件中
prop.store(fos, "split file info");
fis.close();
fos.close();
}
public static void mergeFile(File file, File dir) throws IOException{
//读取配置文件,获取信息
File[] files = dir.listFiles(new Suffix(".properties"));
if(files.length!=1)
throw new RuntimeException("配置文件不存在或不唯一");
Properties prop = new Properties();
FileInputStream os = new FileInputStream(files[0]);
//加载,读取配置文件内容
prop.load(os);
String name = prop.getProperty("filename") ;
int count =Integer.parseInt( prop.getProperty("filecount")) ;
//定义集合,储存文件碎片
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int i = 1; i < count; i ++){
al.add(new FileInputStream(new File(dir,i + ".part")));
}
//利用工具类方法,将集合变成枚举
Enumeration<FileInputStream> en = Collections.enumeration(al);
//创建序列流,将含文件碎片的枚举,变成流对象
SequenceInputStream sis = new SequenceInputStream(en);
//创建输出流,碎片合成文件
FileOutputStream fos = new FileOutputStream(new File(file,name));
byte[] buf = new byte[1024*1024*2];
int len = 0;
while((len = sis.read(buf))!=-1)
{
fos.write(buf, 0, len);
}
sis.close();
fos.close();
}
}
练习:按字节截取字符串
package 复习;
import java.io.IOException;
/**
* 需求:切割字符串“aa黑马程序员”,如果字符是半个就舍弃
* @author Administrator
*
*/
public class CutString {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String str = "aa黑马程序员";
for(int len = 1; len <= str.getBytes("gbk").length;len ++)
{
System.out.println(cutString(str, len));
}
}
public static String cutString(String str, int len) throws IOException {
// TODO Auto-generated method stub
byte[] buf = str.getBytes("gbk");
int count = 0;
for(int x = len -1; x >= 0; x --)
{
if(buf[x]<0)
count ++;
else
break;
}
if(count%2==0)
return new String(buf,0,len,"gbk");
else
return new String(buf,0,len-1,"gbk");
}
}