Java基础知识(八)

一、HashMap<K,V>集合

1、概述
(1)本身基于哈希表,可以保证键的唯一性。
(2)Map集合只针对键有效,当集合中出现两个键一样时,后者所对应的值会覆盖掉前者所对应的值存储。
2、常见存储类型
(1)HashMap<String,String>;(2)HashMap<Inreger,Inreger>
(3)HashMap<Student,String>;(4)HashMap<String,Student>
3、当键的类型不同时
(1)键为自定义类型时,键可重复,若要保证键的唯一性,需在自定义类中重写equals()方法和hashCode()方法。
(2)键非自定义类型时,键唯一,无需重写equals()方法和hashCode()方法。
4、HashMap集合与HashTable集合区别
(1)共同点:都是map接口的实现类,都是基于哈希表的实现类。
(2)HashMap集合:线程不安全的类,不同步,执行效率高(允许键和值是null)。
(3)HashTable集合:线程安全的类,同步,执行效率低(不允许有null键和null值)。
5、例如:
(1)测试类代码

package 集合.HashMap集合;

import java.util.HashMap;
import java.util.Set;

public class Demo {
    public static void main(String[] args) {
        //创建HashMap对象
        HashMap<Student,String> hm=new HashMap<Student,String>();
        //创建自定义类对象
        Student s1=new Student("章泽天",26);
        Student s2=new Student("黄灿灿",27);
        Student s3=new Student("章泽天",26);
        //存储
        hm.put(s1, "北大");
        hm.put(s2, "武大");
        hm.put(s3, "清华");
        //获取所有键
        Set<Student> set=hm.keySet(); 
        //遍历
        for(Student key:set) {
            String value=hm.get(key);
            System.out.println(key.getName()+","+key.getAge()+","+value);
        }
    }
}

(2)自定义类代码

package 集合.HashMap集合;

public class Student {
    private String name;
    private int age;
    public Student() {
        // TODO Auto-generated constructor stub
    }
    public Student(String name,int age) {
        // TODO Auto-generated constructor stub
        this.name=name;
        this.age=age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
}

(3)运行结果
Java基础知识(八)

二、LinkedHashMap<K,V>集合

1、概述:是Map接口基于哈希表和链接列表实现的。
2、特点:键唯一,且元素有序。
(1)保证键的唯一性:哈希表。
(2)保证元素有序性(存储和取出一致):链接列表。

三、TreeMap<K,V>集合

1、概述:基于红黑树结构的Map接口的实现。
2、特点:键值唯一,且可排序。
3、键为自定义类型时:若需要结果以某种顺序输出,需使用自然排序或选择器排序。
4、例如:采用选择器排序
(1)测试类代码:

package 集合.TreeMap集合;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;

import 集合.HashMap集合.Student;

public class Test {
    public static void main(String[] args) {
        //创建集合对象,采用选择器排序接口匿名类对象的方式对输出结果进行排序
        TreeMap<Student,String> tm=new TreeMap<Student,String>(new Comparator<Student>() {
            //重写Comparator接口的compare()方法
            @Override
            public int compare(Student s1, Student s2) {
                //主要排序条件,年龄从小到大
                int num1=s1.getAge()-s2.getAge();
                //次要排序条件,姓名长度由短到长
                int num2=(num1==0)?s1.getName().length()-s2.getName().length():num1;
                return num2;
            }   
        });
        //创建自定义类对象
        Student s1=new Student("zhangzetian",26);
        Student s2=new Student("huangcancan",27);
        Student s3=new Student("zhangzetian",26);
        Student s4=new Student("lijian",38);
        Student s5=new Student("yangzi",26);
        //存储
        tm.put(s1, "北大");
        tm.put(s2, "武大");
        tm.put(s3, "清华");
        tm.put(s4, "清华");
        tm.put(s5, "北影");
        //获取所有键
        Set<Student> set=tm.keySet(); 
        //遍历
        for(Student key:set) {
        String value=tm.get(key);
        System.out.println(key.getName()+","+key.getAge()+","+value);
        }   
    }
}

(2)自定义类代码:

package 集合.TreeMap集合;

public class Student {
    private String name;
    private int age;
    public Student() {
        // TODO Auto-generated constructor stub
    }
    public Student(String name,int age) {
        // TODO Auto-generated constructor stub
        this.name=name;
        this.age=age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

(3)运行结果:
Java基础知识(八)

四、Collections

1、概述:正对集合操作的工具类。
2、特有功能
(1)public static <T> int binarySearch(List<T> list, T key)
二分查找
(2)static T max(Collection coll)获取集合中的最大值
(3)public static void reverse(List<?> list)将集合中的元素顺序反转
(4)public static void shuffle(List<?> list)将集合中的元素打乱,随机置换
(5)public static void sort(List<T> list)排序
3、Collection和Collections区别
(1)Collection:顶层次单列集合的根接口,是一个集合,是一个接口。
(2)Collections:是针对集合操作的工具类,特有功能:随机置换,二分查找,将集合的元素进行反转等。
4、例如
(1)代码:

package 集合.Collections类;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<Integer> list=new ArrayList<Integer>();
        //添加元素
        list.add(8);
        list.add(29);
        list.add(5);
        list.add(23);
        list.add(11);
        //输出集合
        System.out.println("list集合:"+list);
        //排序
        Collections.sort(list);
        System.out.println("sort:"+list);
        //二分查找
        int index=Collections.binarySearch(list,11);
        System.out.println("binarySearch:"+index);
        //反转集合中元素顺序
        Collections.reverse(list);
        System.out.println("reverse:"+list);
        //随机置换
        Collections.shuffle(list);
        System.out.println("shuffle:"+list);
        //求最大值
        int max=Collections.max(list);
        System.out.println("max:"+max);
    }
}

(2)运行结果:
Java基础知识(八)

五、Exception

1、Throwable 类:Java 语言中所有错误或异常的超类。分为error和exception两类。
2、Error:严重错误。例如:内存溢出。
3、Exception:异常
(1)运行时期异常:RuntimeException,编译通过,但开发者代码不严谨,无需显示处理,可像编译时期异常处理。
(2)编译时期异常:非运行时期异常,编译不能通过,开发者必须处理。

4、异常处理
(1)捕获异常(标准):try...catch...finally
A、变形格式:try...catch.../try...catch...catch.../catch...等
B、标准格式:
try{
可能出现异常的代码(越少越好)
}catch(异常类 异常类对象){
处理异常
当try中的异常正好与catch中的异常匹配时,此时会执行catch中的代码
}finally{
释放资源
}
C、处理多个异常(JDK7以后的功能):
try{
可能出现异常的代码(越少越好)
}catch(异常类1|异常类2|异常类3…… 异常类对象){
处理异常
当try中的异常正好与catch中的异常匹配时,此时会执行catch中的代码。
(catch中的异常必须为同一级别的异常)
}finally{
释放资源(finally语句体一定会执行的,除非是Jvm退出。)
}
D、捕获异常处理过程:执行try里面的代码,若出现异常,try会通过代码中的问题创建一个异常对象,然后判断异常对象和catch里面的异常类是否一致, 如果一致,catch里面的代码就会执行Throwable里面的方法。
(2)抛出异常:
A、throws...表示抛出异常,后面跟的异常类名,并且可以多个异常类名中间用逗号隔开。在方法上抛出,由调用者处理,表示抛出异常的可能性。
a、格式:修饰符 返回值 方法名() throws 异常类名{……}
b、throws抛出异常时,跟在方法后面。
B、throw...抛出异常,抛出的是一个异常对象。在语句体中抛出的,由语句体进行处理,表示抛出异常的肯定性。
a、格式:throw new 异常类名(),采用匿名对象的方式。

5、Throwable常用方法
(1)public String getMessage() :消息字符串
(2)public String toString(): 异常的简短描述 ": ",由冒号和空格组成。
(3)public void printStackTrace():包含了消息字符串,还有": "信息描述,具体出现异常的代码定位以及定位的源码上。
上述三种方法,主要用在catch代码部分。

6、自定义异常类
(1)方式1:自定义一个类,继承自Exception
(2)方式2:自定义一个类,继承自RuntimeException
(3)例如:
自定义类:

public class MyException extends Exception {

    public MyException() {}

    public MyException(String message) {
        super(message);
    }
}

测试类:

package 异常.自定义类异常;

import java.util.Scanner;

public class ExceptionTest {
    public static void main(String[] args) throws  MyException{
        Scanner sc=new Scanner(System.in) ;
        System.out.println("请输入学生成绩:");
        int score=sc.nextInt();
        //调用成绩校验方法
        check(score);
    }
    public static void check(int score) throws MyException{
        if(score<0||score>100) {
            //抛出异常对象
            throw new MyException("该学生成绩不合理");
        }else {
            System.out.println("该学生成绩合理!");
        }
    }
}

运行结果:
Java基础知识(八)

7、异常类中注意事项
(1)子类重写父类的方法的时候,子类的方法的抛出的异常要么是父类的方法异常一样,要么是父类方法异常的子类。
(2)子类重写父类方法的时候,如果父类中的这个方法没有抛出异常,那么子类重写的这个方法也不能抛出异常,只能try...catch。
(3)finally语句体一定会执行的,除非是Jvm退出。

8、常见面试题
(1)final、finally、finalize三者区别?
final:可修饰类,该类不能被继承;修饰变量,该变量为常量;修饰成员方法,给成员方法不能被重写。
finally:释放资源。
finalize:与垃圾回收器有关的方法。gc(),运行垃圾回收器,实际是调用finalize()方法。
(2)如果catch里面有return 语句,finally中的代码还会执行,是在return语句之前执行还是return后执行?
finally中代码一定会执行,是在return前执行。
(3)throws和throw的区别?
throws:表示抛出异常,后跟的异常类名,并且可以多个异常类名中间逗号隔开,在方法上抛出,由调用者处理,表示抛出异常的可能性。
throw:表示抛出异常,抛出的是一个异常对象,在语句体中抛出的,由语句体进行处理,表示抛出异常的肯定性。

六、File类

1、概述:表示文件或者目录的路径的抽象表现形式。
2、创建文件对象功能
(1)public File(String pathname):pathname的抽象路径的表现形式,创建一个新 File 实例 (开发中使用)。
(2)public File(String parent,String child)根据 parent 路径和 child 路径创建一个新 File 实例。
(3)public File(File parent, String child)根据一个file对象和一个文件路径来构造File实例。
上述三种方式都表示文件/目录的路径的抽象形式。
3、创建功能(返回值为能否创建成功)
(1)public boolean createNewFile():创建文件,当文件不存在的时候,创建此抽象路径下的文件。
(2)public boolean mkdir():创建一个文件夹,若文件夹不存在,创建成功,否则创建失败。
(3)public boolean mkdirs():创建文件夹,如果父目录不存在,此目录创建成功,否则是创建失败。
(4)例如:

package File类.创建;

import java.io.File;
import java.io.IOException;

public class Chuangjian {
    public static void main(String[] args) throws  IOException{
        File file1=new File("e:\\JavaSE\\大脑袋.txt");
        System.out.println("creatNewFile:"+file1.createNewFile());
        File file2=new File("e:\\BR");
        System.out.println("mkdir:"+file2.mkdir());
        File file3=new File("e:\\BR苏苏不酥");
        System.out.println("mkdirs:"+file3.mkdirs());
    }
}

4、删除功能(返回值为是否删除成功)
(1)public boolean delete():删除文件或者文件夹(目录不能是空的):逐一删除文件或者目录。
(2)例如:

package File类.删除;

import java.io.File;

public class DelectFile {
    public static void main(String[] args) {
        File file=new File("e:\\JavaSE\\大脑袋.txt");
        System.out.println("deleteFile:"+file.delete());
    }
}

5、重命名功能(返回值为是否重命名成功)
(1)public boolean renameTo(File dest):重新命名此抽象路径名表示的文件。
(2)若需重命名的文件与重命名的名称路径名一致,则只是重命名。若两次路径名称不一致,则是重命名,并且剪切。
(3)例如:

package File类.renameToFile;

import java.io.File;

public class RenameToFile {
    public static void main(String[] args) {
        File file1=new File("e:\\BR");
        File file2=new File("e:\\火娃");
        System.out.println("RenameToFile:"+file1.renameTo(file2));
    }
}

6、判断功能
(1)public boolean isDirectory():判断是否是文件夹。
(2)public boolean isFile() :判断是否是文件。
(3)public boolean canRead(): 判断是否可读。
(4)public boolean canWriter():判断是否可写。
(5)public boolean exists() :判断是否存在。
(6)public boolean isHidden():判断是否是隐藏文件。

7、获取功能(重点)
(1)public String getAbsolutePath()获取抽象文件的绝对路径。
(2)public String getPath()获取相对路径的字符串。
(3)public String getName()返回由此抽象路径名表示的文件或目录的名称。
(4)public long length()返回由此抽象路径名表示的文件的长度。
(5)public long lastModified()文件最后一次被修改的时间(时间毫秒值)
(6)例如:

package File类.获取;

import java.io.File;

public class GetTest {
    public static void main(String[] args) {
        File file=new File("e:\\火娃");
        System.out.println("getAbsolutePath:"+file.getAbsolutePath());
        System.out.println("getPath:"+file.getPath());
        System.out.println("getName:"+file.getName());
        System.out.println("length:"+file.length());
        System.out.println("lastModified:"+file.lastModified());
    }
}

运行结果:
Java基础知识(八)

8、高级功能(重点)
(1)获取当前某个路径下的所有的文件夹以及文件名称的字符串数组:
A、public String[] list()获取全部
B、public String[] list(FilenameFilter filter)过滤后获取
(2)获取当前某个路径下所有的文件夹以及文件的File数组:
A、public File[] listFiles()获取全部
B、public File[] listFiles(FilenameFilter filter)过滤后获取
补充:FilenameFilter,一个接口,文件名称过滤器。
(3)例如:获取f盘下所有文件夹/文件的名称

package File类.高级;

import java.io.File;

public class GetEfile {
    public static void main(String[] args) {
        File file=new File("f:\\");
        //获取存储文件名称的字符串数组
        String[] list=file.list();
        //遍历获取的字符串数组
        for(String str:list) {
            System.out.println("String[]:"+str);
        }
        System.out.println("------------------------------");
        //获取存储文件名称的文件数组
        File[] listfiles=file.listFiles();
        //遍历获取的文件数组
        for(File f:listfiles) {
        System.out.println("File[]:"+f);
        }           
    }
}

运行结果:
Java基础知识(八)
Java基础知识(八)

9、测试功能
(1)boolean accept(File dir, String name)测试指定文件是否应该包含在某一文件列表中。
(2)该方法是FilenameFilter接口中的方法,当高级功能过滤文件需要时,重写该方法。

例题:判断F盘下是否有后缀名为.rar的文件,若有输出此文件名称。

package File类.高级;

import java.io.File;
import java.io.FilenameFilter;

public class GuoLv {
    public static void main(String[] args) {
        File file=new File("F:\\");
        //获取存储文件名称的字符串数组,采用文件过滤器,匿名内部类方式筛选文件
        String[] list=file.list(new FilenameFilter() {
            //重写FilenameFilter接口中的accept()方法
            @Override
            public boolean accept(File dir, String name) {
                //创建文件对象,并指定路径
                File f=new File(dir,name);
                //判断是否为文件
                boolean flag1=f.isFile();
                //判断后缀名是否为.rar
                boolean flag2=name.endsWith(".rar");
                return flag1&&flag2;
            }       
        });
        //遍历获取的字符串数组
        for(String str:list) {
            System.out.println("String[]:"+str);
        }
    }
}

运行结果:
Java基础知识(八)

10、路径分类
(1)绝对路径(带盘符):盘符名:\xx\xx.后缀名
(2)相对路径(不带盘符):xx.后缀名

11、创建文件时,如果未写盘符,创建位置:创建在当前的路径项目下。

七、IO流(对文件进行操作)

1、概述:设备和设备之间的一种数据传输。

2、IO流分类
(1)按流的方向分:
A、输入流:读取文件,把硬盘上文件读取出来后输出文件内容。
B、输出流:写文件,将从某硬盘上读取的内容,写在另一硬盘上。
(2)按数据的类型划分:
A、字节流(对文本文件进行操作时优先选择)
a、字节输入流:InputStream,读取字节,读取字节输入流的所有类的超类。
b、字节输出流:OutputStream,写字节,写字节输出流的所有类的超类。
B、字符流
a、字符输入流:Reader,读取字符,读取字符的抽象类。
b、字符输出流:Writer,写字符,写字符的抽象类。

3、实例化
(1)使用字节流进行操作,无法创建字节输入/出流对象InputStream/OutputSteam 抽象类,不能实例化,需要通过其子FileInputSteam/FileOutputSteam进行实例化。
(2)使用字节流进行操作,无法创建字符输入/出流对象Reader/Wirter抽象类,不能实例化,需要通过其子FileReader/FileWirter进行实例化。

4、不同操作系统的换行符号
(1)windows:\r\n
(2)linux:\n
(3)mac:\r
(4)一些高级记事本对任何的换行符号都会有效果。

5、开发步骤
(1)创建字节/字符输入/输出流对象;
(2)读/写数据;
(3)关闭资源。

6、OutputStream
(1)概述:抽象类,字节输出流。
(2)子实现类:FileOutputStream
(3)例如:给e盘中火娃文件夹中的大脑袋文件写入“br”内容:

package IO流.OutputStream类;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputStreamDemo {
    public static void main(String[] args) throws FileNotFoundException,IOException{
        //创建字节输出流对象
        FileOutputStream fos=new FileOutputStream("e:\\火娃\\大脑袋");
        //使用流对象给文件写数据
        fos.write("br".getBytes());
        //关闭资源
        fos.close();
    }
}

7、字节输出流写数据方法
(1)public void write(int b):一次写一个字节
(2)public void write(byte[] b) :一次写一个字节数组
(3)public void write(byte[] b, int off,int len):一次写一部分字节数组
(4)例如:

package IO流.OutputStream类;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputFangfa {
    public static void main(String[] args) throws FileNotFoundException,IOException{
        //创建字节输出流对象
        FileOutputStream fos=new FileOutputStream("e:\\火娃\\大脑袋");
        //一次写一个字节
        fos.write(97);
        //定义一个字节数组
        byte[] bys= {97,48,98};
        //一次写一个字节数组
        fos.write(bys);
        //一次写字节数组的一部分
        fos.write(bys,0,2); 
        //关闭资源
        fos.close();
    }
}

8、末尾追加数据功能
(1)public FileOutputStream(File file, boolean append):指定为true,末尾追加数据。
(2)例如:

package IO流.OutputStream类;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class AppendDemo {
    public static void main(String[] args) throws FileNotFoundException,IOException{
        //创建字节输出流对象
        FileOutputStream fos=new FileOutputStream("e:\\火娃\\大脑袋",true);
        //写数据
        for(int x=0;x<10;x++) {
            //追加内容
            fos.write(("hello"+x).getBytes());
            fos.write(("\r\n"+x).getBytes());
        }
        //关闭资源
        fos.close();
    }
}

9、IO流中加入异常处理
(1)标准格式:try...catch...finally...
(2)注意事项:finally访问该对象时,需将该对象放在try语句外面。
(3)例如:

package IO流.OutputStream类;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class IOexceptin {
    public static void main(String[] args) throws FileNotFoundException,IOException{
        //创建字节输出流对象
        FileOutputStream fos=null;
        try {
            fos=new FileOutputStream("e:\\火娃\\大脑袋");
            fos.write("bighead".getBytes());
        }catch(IOException e){
            //处理异常
            e.printStackTrace();
        }finally {//释放资源
            if(fos!=null) {
                try {
                    fos.close();
                }catch(IOException e1){
                    e1.printStackTrace();
                }
            }
        }               
    }
}

10、InputStream
(1)概述:抽象类,字节输入流。
(2)子实现类:FileInputStream
(3)构造方法:public FileInputStream(String name)
11、数据读取方式
(1)public abstract int read()一次读取一个字节
(2)public int read(byte[] b)一次读取一个字节数组 (读取实际的字节数),指定字节数的长度时一般指定为1024的倍数。(效率大于第一种方式)。
(3)例如:
方法一:一次读取一个字节

package IO流.InputStream;

import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;

public class ReadDemo {
    public static void main(String[] args) throws FileNotFoundException,IOException{
        //创建字节输出流对象
        FileInputStream fis=new FileInputStream("e:\\火娃\\大脑袋");
        int by=0;
        //当fis文件不为空时读取字节
        while((by=fis.read())!=-1) {
            System.out.println((char)by);
        }
        //关闭资源
        fis.close();
    }
}

方法二:一次读取一个字节数组

package IO流.InputStream;

import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;

public class ReadDemo {
    public static void main(String[] args) throws FileNotFoundException,IOException{
        //创建字节输出流对象
        FileInputStream fis=new FileInputStream("e:\\火娃\\大脑袋");
        int by=0;
        //当fis文件不为空时读取字节
        while((by=fis.read())!=-1) {
            System.out.println((char)by);
        }
        //关闭资源
        fis.close();
    }
}

11、复制文件
(1)读取源文件:FileInputStream
(2)输出目的地文件:FileOutputStream
(3)例1:复制文本文件,一次读取一个字节

package IO流.Copy;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy1 {
    public static void main(String[] args) throws  FileNotFoundException, IOException{
        //定义源文件输入流对象
        FileInputStream fis=new FileInputStream("e:\\BR苏苏不酥\\大脑袋");
        //定义目的地文件输出流对象
        FileOutputStream fos=new FileOutputStream("e:\\BR苏苏不酥\\bighead");
        int by=0;
        while((by=fis.read())!=-1) {
            fos.write(by);
        }
        fos.close();
        fis.close();
    }
}

(4)例2:复制jpg文件,一次读取一个字节数组

package IO流.Copy;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy2 {
    public static void main(String[] args) throws  FileNotFoundException, IOException{
        //定义源文件输入流对象
        FileInputStream fis=new FileInputStream("e:\\BR苏苏不酥\\大脑袋.jpg");
        //定义目的地文件输出流对象
        FileOutputStream fos=new FileOutputStream("e:\\BR苏苏不酥\\bighead.jpg");
        byte[] by=new byte[1024];
        int len=0;
        while((len=fis.read())!=-1) {
            fos.write(by,0,len);
        }
        fos.close();
        fis.close();
    }
}

猜你喜欢

转载自blog.51cto.com/13678728/2117534