一、Map容器(抽象类)

Map容器:长度不固定,可随意添加元素,底层通过键值对来存储数据,元素的值和下标的键绑定,通过键来访问元素,键可以是任意类型(键相当于数组的下标)。

1、特点

(1)长度不固定;
(2)键的值不能重复;
(3)值可以重复。

2、实现类

HashMap类:底层通过哈希表实现数据的存储,线程不安全,效率较高,使用较多;键和值可以为null;
HashTable类:底层通过哈希表实现数据的存储,线程安全,效率较低,使用较少;键和值不能为null;
TreeMap类:底层通过红黑树实现数据的存储,性能比HashMap差,可对键升序排列,一般不用;
Properties类:继承自HashTable.

3、常用API的使用

(1)put(key,value):添加或者修改数据,若原来存在key值,则修改数据;
(2)get(key):通过键获取值;
(3)remove(key):通过键移出键值对,即数据;
(4)clear():清楚所有数据;
(5)size():获取数据的总个数;
(6)booleancontainsKey(key):是否包含key键对应的键值对,有则返回true;
(7)booleancontainsValue(value):是否包含value所对应得键值对,有则返回true;
(8)map.values():获取所有得值,返回包含值得Collection集合;
(9)map.keySet():获取所有得键,返回Set集合;
(10)map.entrySet():获取所有得键值对得Set集合;

4、Map容器的遍历

(1)方法一:先获得所有得键,再通过键获得所有得值

例如:有一个Students类的Map集合

  1. //获取所有的值
  2. Collection<Student> stus = students.values();
  3. //遍历集合:打印名字
  4. for(Student stu:stus) {
  5. System.out.println(stu.getName());
  6. }
  7. //获取所有的键
  8. Set<String> nums = students.keySet();
  9. //遍历nums得到所有的键
  10. System.out.println("---所有的键----");
  11. for(String num:nums) {
  12. System.out.print("键:"+num);
  13. //有了键可以获取值
  14. Student stu = students.get(num);//通过键来获取值
  15. System.out.println("-值:"+stu.getName());

(2)方法二:先获取所有得键值对,再通过遍历所有得键值对得Set集合获得所有得值

例如:有一个Students类的Map集合

  1. //map.entrySet(); - 获取所有的键值对(返回包含所有键值对的set集合)
  2. Set<Entry<String,Student>> entry = students.entrySet();
  3. //遍历set集合
  4. for(Entry<String,Student> e:entry) {
  5. //获取键:getKey()
  6. String num = e.getKey();
  7. System.out.print("学号:"+num);
  8. //获取值:getValue()
  9. Student stu = e.getValue();//直接获取值:效率比map.get(key)高
  10. System.out.println("-学生:"+stu.getName());
  1. }

二、IO输入输出流

程序数据间的转移称为流,程序中的输入和输出以程序为中心:读取数据称为输入(输入程序);从程序输出内容到文件称为输出(从程序输出,写入文件)。
1、按流向分为:输入流(InputStrream或者Reader)和输出流(OutputStream或者Writer)
2、按类型分为:字节流和字符流(重点掌握);

(1)、字节流输入(InputStream)

可用于输入各种类型的文件,包括:文本文档,视频,图片,音频等;
常用API的使用
1)read():读取文件;
2)read(byte[] b):通过byte数组读取文件;
3)read(byte[] b,offset,int len):按长度和索引读取文件;
4)close():关闭流管道;
读取数据的步骤:
1)创建数据源文件
2)建立输入流管道,链接到数据源
3)通过输入流管道读取数据
4)关闭输入流管道

(2)字节流输出(OnputStream)

可用于输出各种类型的文件,包括:文本文档,视频,图片,音频等;
常用API的使用
1)write():输出文件;
2)write(byte[] b):通过byte数组读取文件;
3)write(byte[] b,offset,int len):按长度和索引读取文件;
4)flush():刷新管道
5)close():关闭流管道;
输出数据的步骤:
1)创建数据源文件(目的地)
2)建立输出流管道,链接到数据目的地
3)通过输出流管道输出数据
4)刷新管道
5)关闭输入流管道

(3)字符流输入(Reader)

只能输入文本文档。
常用API的使用
1)read():读取文件;
2)read(char[] ch:通过char数组读取文件;
3)close():关闭流管道;
读取数据的步骤:
1)创建数据源文件
2)建立输入流管道,链接到数据源
3)通过输入流管道读取数据
4)关闭输入流管道
例题:

public static void test1() {
        //1、创建数据源对象
        File file = new File("D:/File/reader.txt");
        //2、创建管道(字符输入流)连接数据源
        Reader reader = null;
        try {
            reader = new FileReader(file);
            //3、通过字符输入流读取数据:直接读取字符数据
            char[] chars = new char[4];
            int readLen = 0;//读取到的字符的长度
            //循环读取字符数据
            while((readLen=reader.read(chars))!=-1) {//自动进行编码和解码,且使用Java文件当前默认的字符集。
                System.out.println("读取到的数据长度:"+readLen);
                System.out.println("读取到的数据内容:"+Arrays.toString(chars));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(reader!=null) {
                try {
                   reader.close();
                } catch (IOException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                }
            }
        }
    }

(4)字符流输出(Writer)

只用于文本文档的输出。
常用API的使用
1)write():输出文件;
2)write(String str):输出文件;
3)write(char[] ch):输出文件;
4)flush():刷新管道,输出缓冲的数据
5)close():关闭流管道;
输出数据的步骤:
1)创建数据源文件(目的地)
2)建立输出流管道,链接到数据目的地
3)通过输出流管道输出数据
4)刷新管道
5)关闭输入流管道
例题:

public static void test1() {
        //1.创建数据输出的目的地
        File file = new File("D:/File/write.txt");
        //2.建立管道(字符输出流)和数据输出目的地建立链接
        Writer writer = null;
        try {
            writer = new FileWriter(file);
            //3.获取需要写出的数据
            String str = "张靓颖_女_歌手_四川";
            //4、写出数据到目的地
            writer.write(str);
            //5、刷新管道
            writer.flush();
            System.out.println("数据写出完成");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(writer!=null) {
                try {
                   writer.close();
                } catch (IOException e) {
                   e.printStackTrace();
                }
            }
        }
    }

三、例题:复制文件(字节流)

public static void copyFile(File src,File aim) {
        //创建输入输出流管道
        InputStream fin =  null;
        OutputStream fout = null;
        try {
            fin = new FileInputStream(src);
            fout = new FileOutputStream(aim);
            //通过输入流读取数据源的数据
            byte[] buff = new byte[512];
            int readLen = 0;//读取的数据的长度
            //循环读取数据
            while((readLen = fin.read(buff))!=-1) {
                //将gb格式的文件转成utf-8的格式去输出
                String str1 = new String(buff,0,readLen, "gbk");
                //得到以utf-8格式编码的字节数组
                byte[] bytes = str1.getBytes("utf-8");
                //输出字节数组
                fout.write(bytes);
            }
            //刷新管道
            fout.flush();
            System.out.println("复制文件成功");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fout!=null) {
                try {
                   fout.close();
                } catch (IOException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                }
            }
            if(fin!=null) {
                try {
                   fin.close();
                } catch (IOException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                }
            }
        }
    }