Java学习笔记 - 第023天

每日要点

File

directory / folder - 文件夹

Java 7以后I/O(nio.2)中添加了操作文件和路径的工具类
Files - 操作文件的工具类
Paths - 操作路径的工具类
例子1:

        File f = new File("c:/hello/abc/efg");
        // f.mkdir();
        f.mkdirs();
        // 获得绝对路径
        System.out.println(f.getAbsolutePath());
        if (f.isDirectory()) {
            String[] strs = f.list();
            for (String temp : strs) {
                System.out.println(temp);
            }
        }
随机访问文件类

例子2:

        // 随机访问文件
        try (RandomAccessFile raf = new RandomAccessFile("c:/abc.txt", "rw")) {
            raf.seek(6);
            raf.writeUTF("good");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

NIO

JDK 1.4版引入了一套新的I/O系统称之为NIO
Buffer 缓冲区
Channel 通道
CharSet 字符集

NIO - Non-blocking I/O - 非阻塞式的I/O

导出和使用jar文件

导出:
在项目上右键选择Export-java-JAR file

导入:
将jar包负责粘贴到项目中,然后右键jar包选择Build Path

导入jar包后就可以使用jar包中写好的类:
在当前项目中使用其他项目导出的jar文件中的类
jar - java archive - Java归档文件(压缩包)
从别处获得的jar文件必须放到Build Path(类路径)下才能使用
例子1:

class Test04 {

    // 在当前项目中使用其他项目导出的jar文件中的类
    // jar - java archive - Java归档文件(压缩包)
    // 从别处获得的jar文件必须放到Build Path(类路径)下才能使用
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            System.out.println(MyUtil.generateVC(4));
        }
        new VCFrame().setVisible(true);
    }
}

压缩

GZIPInputStream - 读取单个压缩文件 - 解压缩
GZIPOutputStream - 压缩单个文件 - 压缩
ZipOutputStream - 将多个文件压缩成一个文件
ZipInputStream - 读取压缩文件还原成多个文件

给压缩文件添加冗余校验码 - 用于验证压缩文件的正确性和完整性的附加数据

  • Adler32 / CRC32

清空缓冲区(强行把缓冲区中的数据写到输出流中)
bos.flush();
例子1:

class Test05 {

    // GZIPInputStream - 读取单个压缩文件 - 解压缩
    // GZIPOutputStream - 压缩单个文件 - 压缩
    // ZipOutputStream - 将多个文件压缩成一个文件
    // ZipInputStream - 读取压缩文件还原成多个文件
    public static void main(String[] args) {
        try (OutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/test.zip")) {
            // 给压缩文件添加冗余校验码 - 用于验证压缩文件的正确性和完整性的附加数据
            // - Adler32  / CRC32
            CheckedOutputStream cos = new CheckedOutputStream(out, new CRC32());
            ZipOutputStream zos = new ZipOutputStream(cos);
            BufferedOutputStream bos = new BufferedOutputStream(zos);
            String[] filenames = {"java.chm", "git命令.txt", "chess.rar"};
            for (String filename : filenames) {
                zos.putNextEntry(new ZipEntry(filename));
                try (InputStream in = new FileInputStream("C:/Users/Administrator/Desktop/" + filename)) {
                    BufferedInputStream bin = new BufferedInputStream(in);
                    byte[] buffer = new byte[4096];
                    int totalBytes;
                    while ((totalBytes = bin.read(buffer)) != -1) {
                        bos.write(buffer, 0, totalBytes);
                    }
                    // 清空缓冲区(强行把缓冲区中的数据写到输出流中)
                    bos.flush();
/*                  int b;
                    while ((b = bin.read()) != -1) {
                        bos.write(b);
                    }
                    bos.flush();*/
                }
                catch (IOException ioe) {
                    ioe.printStackTrace();
                }
                zos.closeEntry();
            }
            zos.finish();
            System.out.println("压缩完成!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

线程

进程 - process - 操作系统分配内存的基本单元
线程 - thread - 最小的执行单元(操作系统分配CPU资源的基本单位)

一个进程通常包含了一个(主线程)或多个线程

Java中创建线程有三种方式:

  • 继承Thread类并重写run()方法
  • 实现Runnable接口并重写run()方法 (推荐使用!!!)
    • 由于Runnable接口是单方法接口(函数式接口)所以也可以使用Lambda表达式
  • 实现Callable接口并重写call()方法 - 将来时(Java 5+)

创建并启动线程 在新的线程中执行耗时间的任务
需要执行很长的时间如果放在主线程中执行那么主线程中的其他任务,就会被这个耗时间的任务所阻塞 所以耗时间的任务一定要放到主线程之外的线程中

启动线程是调用start()方法不能直接调用run()方法
例子1.

// 进程 - process - 操作系统分配内存的基本单元
// 线程 - thread - 最小的执行单元(操作系统分配CPU资源的基本单位)
// 一个进程通常包含了一个(主线程)或多个线程 

// Java中创建线程有三种方式:
//  - 继承Thread类并重写run()方法
//  - 实现Runnable接口并重写run()方法 (推荐使用!!!)
//     ·由于Runnable接口是单方法接口(函数式接口)所以也可以使用Lambda表达式
//  - 实现Callable接口并重写call()方法 - 将来时(Java 5+)
public class MyFrame extends JFrame implements ActionListener{
    private static final long serialVersionUID = 6221501510348081778L;
    
    private JButton downloadButton, aboutButton;

//  private class DownloadHandler extends Thread {
    @SuppressWarnings("unused")
    private class DownloadHandler implements Runnable {
        
        @Override
        public void run() {
            downloadData();
            downloadButton.setText("下载");
            downloadButton.setEnabled(true);
        }
    }
    
    public MyFrame() {
        this.setTitle("下载");
        this.setSize(450, 200);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        this.setLayout(null);
        
        downloadButton = new JButton("下载");
        downloadButton.setBounds(120, 120, 80, 30);
        downloadButton.addActionListener(this);
        aboutButton = new JButton("关于");
        aboutButton.setBounds(250, 120, 80, 30);
        aboutButton.addActionListener(this);
        this.add(downloadButton);
        this.add(aboutButton);
    }
    
    public static void main(String[] args) {
        new MyFrame().setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == downloadButton) {
            downloadButton.setEnabled(false);
            downloadButton.setText("下载中");
            // 创建并启动线程 在新的线程中执行耗时间的任务
            // 启动线程是调用start()方法不能直接调用run()方法
        //  new DownloadHandler().start();
        //  new Thread(new DownloadHandler()).start();
            // Lambda表达式写法
            Thread thread = new Thread(() -> {
                    downloadData();
                    downloadButton.setText("下载");
                    downloadButton.setEnabled(true);
                });
            // 设置优先级
            thread.setPriority(Thread.NORM_PRIORITY);
            // 设置守护进程(不值得保留的线程 - 主线程一结束该线程不保留)
            thread.setDaemon(true);
            // 启动线程
            thread.start();
        }
        else if (source == aboutButton) {
            JOptionPane.showMessageDialog(null, "欢迎使用xXx软件1.0版!\n作者: Kygo");
        }
        
    }

    // 下载任务需要执行很长的时间如果放在主线程中执行那么主线程中的其他任务
    // 就会被这个耗时间的任务所阻塞 所以耗时间的任务一定要放到主线程之外的线程中
    // 因此下面的方法应该在一个新的线程中去调用它而不是在主线程中直接调用
    private void downloadData() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

练习1.启动两个线程 一个负责输出hello 一个负责输出good

class PrintThread implements Runnable {
    private String str;
    private int counter;

    public PrintThread(String str, int counter) {
        this.str = str;
        this.counter = counter;
    }

    @Override
    public void run() {
        for (int i = 0; i < counter; i++) {
            System.out.print(str);
            doNothing();
        }
    }
    
    private void doNothing() {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
}

class Test01 {
    
    public static void main(String[] args) {
        new Thread(new PrintThread("hello", 100)).start();
        new Thread(new PrintThread("good", 100)).start();
    }
}

杂项

.getClass .Class 获得这个类的原数据对象

例子1:字符串题

class Test01 {

    public static void main(String[] args) {
        String s1 = "go";
        String s2 = "od";
        String s3 = "good";
        String s4 = "go" + "od";  // 两个常量相加 引用放在常量池
        // javap 反编译源文件 先new分配空间 再初始化StringBuilder append append .toString
        String s5 = s1 + s2; 
        System.out.println(s4 == s3);
        System.out.println(s5 == s3);
    }
}

例子2:
非静态内部类的对象一定要依赖于外部类的对象才能创建出来
静态内部类对象的创建可以不依赖于外部类的象

class Test06 {

    public class Foo {
        
    }
    
    public static void main(String[] args) {
        Test06 t = new Test06();
        // 非静态内部类的对象一定要依赖于外部类的对象才能创建出来
        // 静态内部类对象的创建可以不依赖于外部类的象
        Foo foo = t.new Foo();
    }
}

昨日作业讲解

**作业:建一个文本文件 写很多话 做一个窗口 随机显示一句话 点一下换一句 **

public class MyFrame extends JFrame {
    private static final long serialVersionUID = 5056783142767245993L;
    
    private JLabel contentLable;
    
    private List<String> contentsList = new ArrayList<>();
    
    public MyFrame() {
        loadData();
        
        this.setTitle("每日一句");
        this.setSize(350, 120);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        contentLable = new JLabel(randomContent(), JLabel.CENTER);
        this.add(contentLable);
        
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                contentLable.setText(randomContent());
            }
        });
    }
    
    private void loadData() {
        // .getClass  .Class 获得这个类的原数据对象
        ClassLoader loader = this.getClass().getClassLoader();
        InputStream in = loader.getResourceAsStream("名言警句.txt");
        Reader reader = new InputStreamReader(in);
        try (BufferedReader br = new BufferedReader(reader)) {
            String str;
            while ((str = br.readLine()) != null) {
                contentsList.add(str);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private String randomContent() {
        int randomIndex = (int) (Math.random() * contentsList.size());
        return contentsList.get(randomIndex);
    }

    public static void main(String[] args) {
        new MyFrame().setVisible(true);
    }
}

作业

QQ截图20161228173936.png

1.做一个窗口,实现5辆车多线程跑
车类:

public class Car{
    
    private int x;
    private int y;
    private int width;
    private int height;
    private Color color;
    private boolean isEnd;
    
    public Car(int x, int y) {
        this.x = x;
        this.y = y;
        this.color = randomColor();
        this.width = 60;
        this.height = 30;
    }
    
    public void move() {
        if (x < 530) {
            x += Math.random() * 10 + 1;
        }
    }
    
    public boolean isEnd() {
        if (x > 530) {
            isEnd = true;
        }
        return isEnd;
    }
    
    private Color randomColor() {
        return new Color((int) (Math.random() * 256), 
                (int) (Math.random() * 256), (int) (Math.random() * 256));
    }
    
    public void draw(Graphics g) {
        g.setColor(color);
        g.fillRect(x, y, width, height);
    }
}

窗口类:

public class MyFrame extends JFrame {
    
    private static final long serialVersionUID = 1581122281838520043L;
    
    private BufferedImage image = new BufferedImage(600, 400, 1);
    
    private List<Car> carsList = new ArrayList<>();
    private List<Thread> carsThread = new ArrayList<>();
    
    public MyFrame() {
        this.setTitle("赛车游戏");
        this.setSize(600, 400);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        for (int i = 0; i < 5; i++) {
            carsList.add(new Car(60, 80 + i * 50));
        }
        
        for (int i = 0; i < 5; i++) {
            Car car = carsList.get(i);
            carsThread.add(new Thread(() -> {           
                while (!car.isEnd()) {
                    car.move();
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    repaint();  
                }
            }));
        }
        for (Thread thread : carsThread) {
            thread.start();
        }
    }
    
    @Override
    public void paint(Graphics g) {
        Graphics otherGraphics = image.getGraphics();
        super.paint(otherGraphics);
        for (Car car : carsList) {
            car.draw(otherGraphics);
        }
        otherGraphics.setColor(Color.BLACK);
        ((Graphics2D) otherGraphics).setStroke(new BasicStroke(5));
        otherGraphics.drawLine(530, 0, 530, 400);
        g.drawImage(image, 0, 0, null);
    }
    
    public static void main(String[] args) {
        new MyFrame().setVisible(true);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容