2018-07-19


今日学习

  • java集合/本地文件操作/IO操作/多线程
  • 单例模式

一:集合类

Collection接口

  • 可以理解为一个动态的对象数组,不同的时集合中的对象内容可以任意扩充
  • 特点
    • 性能高
    • 容易扩展和修改
  • Collection的常用子类
    • List:可以存放任意数据,可重复(在迭代输出时,不能对集合的元素进行删除操作)
      • ArrayList:非线程安全,异步处理,性能高
      • Vector:线程安全,同步处理,性能低
    • Set:不能重复,可以排序
      • HashSet
      • TreeSet:有序排放
    • Queue:先进先出
        List<String> lists = null;
        lists = new ArrayList<>();
        lists.add("A");
        lists.add("B");
        for(int i=0; i<lists.size();i++){
            System.out.println(lists.get(i));
        }
        lists.remove(0);
        // 查询是否存在
        System.out.println("indexOf "+lists.indexOf("K"));
        // 是否为空
        System.out.println("isEmpty "+lists.isEmpty());

Iterator接口(迭代器)

  • 集合输出的标准操作
  • 专门的迭代输出接口,将元素一个个进行判断,判断其是否有内容,如果有内容,就取出
  • 只能单向移动
  • 元素被访问的顺序取决于集合的类型
  • 调用next时,迭代器就越过下一个元素,并返回刚刚越过的那个元素的引用
        List<String> list = new ArrayList<>();
        list.add("D");
        list.add("K");
        list.add("O");
        // iterator方法返回一个实现了Iterator接口的对象,可以使用这个迭代器对象依次访问集合中的元素
        Iterator<String> iter = list.iterator();
        //删除第一个元素
        iter.next();
        iter.remove();
        while(((Iterator) iter).hasNext()){
            String str = iter.next();
            if ("K".equals(str)){
                iter.remove();
            }else {
                System.out.println(iter);
            }
        }
//      iter.forEachRemaining(element -> System.out.println("!"+element));

Map接口

  • HashMap
  • HashTable

        Map<String,String> map = new HashMap<>();
        map.put("k1","jikexy");
        map.put("k2","www");
        map.put("k3","com");
        map.put("k4","java");
        if (map.containsKey("k3")){  System.out.println("key存在");
        }else {  System.out.println("key不存在");   }
        if (map.containsValue("firefox")){
            System.out.println("value存在");
        }else {  System.out.println("value不存在");}
        // 获取key
        Set<String> s = map.keySet();
        Iterator<String> i = ((Set) s).iterator();
        while(i.hasNext()){  System.out.println(i.next()); }
        // 获取value
        Collection<String> c = map.values();
        Iterator<String> i2 = c.iterator();
        while (i2.hasNext()){   System.out.println(i2.next()); }

二:本地文件操作

文件

        /**
         * 当前的相对目录都是基于项目文件下的
         * "../../Hello.txt" 创建在上上一层文件夹中
         * "../Hello.txt" 创建在上一层文件夹中
         * "Hello.txt" 创建在相对目录处
         * "newFiles/Hello.txt" 创建在相对目录下的newFils文件内
         */

        File file = new File("newFiles/Hello.txt");

        /**
         * 文件的重命名实现文件目录的转换
         * 文件结构必须处于同一个分区
         * 文件处于不同的分区,需要使用文件的拷贝
         */

        if(file.exists()){
            /**
             * 此文件可以是空的,不指向任何实质性的文件,并且文件的路径发生了变化
             * 如果文件已经存在,则文件不会被重命名和转移路径
             */
            File nameto = new File("new Hello2.txt");
            file.renameTo(nameto);
// System.out.println(file.isFile());
// System.out.println(file.isDirectory());
// file.delete();
// System.out.println("文件删除成功");
        }else{
            System.out.println("文件不存在");
            try{
                file.createNewFile();
                System.out.println("文件创建成功");
            }catch (IOException e){
                System.out.println("文件无法创建");
            }
        }

文件夹

        File folder = new File("my new folder");
        if (folder.mkdir()){
            System.out.println("文件夹创建完成");
        }else{
            if(folder.exists()){   System.out.println("文件夹已经存在");
            }else{     System.out.println("文件夹创建失败"); }
        }
        // 空文件夹才能被删除
        if (folder.delete()){
            System.out.println("done"); 
        }else { System.out.println("fail");  }
        //改名
        File f1 = new File("my new folder"); // 此文件必须存在才能改名
        f1.mkdirs(); //创建多级目录
        File f2 = new File("rename folder");
        if (f1.renameTo(f2)){  System.out.println("done");
        }else{    System.out.println("fail"); }

遍历文件夹

public static void printFiles(File dir, int tab){
        if (dir.isDirectory()){
            File next [] = dir.listFiles();
            for (int i =0; i<next.length ; i++){
                for (int j=0; j< tab; j++){
                    System.out.print("|--");
                }
                System.out.println(next[i].getName());
                if (next[i].isDirectory()){
                    printFiles(next[i],tab++);
                }
            }
        }

三:IO操作

  • 基本功能:读和写
  • 字节流:以“Stream”结尾;可以处理所有类型的数据,在读取时,读到一个字节就返回一个字节。
  • 字符流:以“Reader”或“Writer”结尾;仅能处理纯文本数据,在读取时,速到一个或多个字节,先查找指定的编码表,然后将查到的字符返回。

四:多线程编程

线程的实现

  • 继承Thread类
  • 实现Runnable接口
/**
 * 线程实现的两种方法:
 * 1、继承Thread类
 * 2、实现Runnable接口
 * sleep/yield/join/setPriority/getName
 */
class MyThread extends Thread{
    private String name;
    public MyThread(String name){
        this.name = name;
    }
    public void run(){
        for(int i =0;i<10;i++){
            System.out.println(name+":"+i);
        }
    }
}
class MyRunnable implements Runnable{
    private String name;
    public MyRunnable(String name){
        this.name = name;
    }
    @Override
    public void run() {
        for(int i=0; i<100;i++){
// System.out.println("当前线程对象:"+Thread.currentThread().getName());
            System.out.println(this.name+";"+i);
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
            if (i == 10){
                System.out.println("礼让");
                Thread.yield();
            }
        }
    }
}
public class ThreadDemo {
    public static void main(String [] args){
        TestMyThread();
        TestMyRunnable();
    }
    public static void TestMyThread(){
        MyThread t1 = new MyThread("A");
        MyThread t2 = new MyThread("B");
        MyThread t3 = new MyThread("C");
        // 设置优先级
        t1.setPriority(Thread.MIN_PRIORITY);
        t2.setPriority(Thread.NORM_PRIORITY);
        t3.setPriority(Thread.MAX_PRIORITY);
        // 通过start启动线程
        t1.start();
        t2.start();
        t3.start();
    }
    public static void TestMyRunnable(){
        MyRunnable r1 = new MyRunnable("a");
        MyRunnable r2 = new MyRunnable("b");
        Thread t3 = new Thread(r1);
        Thread t4 = new Thread(r2);
        System.out.println(t3.isAlive());
        t3.start();
        System.out.println(t3.isAlive());
        t3.start();
        for (int i = 0;i<50;i++){
            if (i>10){
                try {
                    t3.join(); //强行执行,作用于t1,t2
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("主线程:"+i);
        }
    }
}

3.单例模式

/**
 * 单例模式Singleton
 * 应用场合:有些对象只需要一个就足够了,如古代皇帝
 * 作用:保证整个应用程序中某个实例有且只有一个
 * 类型:饿汉模式、懒汉模式
 */
//饿汉模式
class Singleton{
    // 1、将构造方法私有化,不允许外部直接创建对象
    private Singleton(){  }
    // 2、创建类的唯一实例,使用private static修饰
    private static Singleton instence = new Singleton();
    // 3、提供一个用于获取实例的方法,使用public static
    public static Singleton getInstence(){
        return instence;
    }
}
// 懒汉模式
class Singleton2{
    // 1、将构造方法私有化,不允许外部直接创建对象
    private Singleton2(){
    }
    // 2、创建类的唯一实例,使用private static修饰
    private static Singleton2 instance;
    // 3、提供一个用于获取实例的方法,使用public static
    public static Singleton2 getInstance(){
        if(instance == null){
            instance = new Singleton2();
        }
        return instance;
    }
}
public class SingletonDemo {
    public static void main(String [] args){
        Singleton s1 = Singleton.getInstence();
        Singleton s2 = Singleton.getInstence();
        if (s1 == s2){
            System.out.println("s1和s2是同一个实例");
        }
        Singleton2 s3 = Singleton2.getInstance();
        Singleton2 s4 = Singleton2.getInstance();
        if (s3 == s4){
            System.out.println("s3和s4是同一个实例");
        }
    }
}
  • 区别: 饿汉:线程安全,加载类时比较慢,但运行时获取对象的速度比较快; 懒汉:线程不安全,加载类时比较快,但运行时获取对象的速度比较慢;