Java学习总结第五篇

本文介绍了线程间通信的wait/notify机制,通过生产者消费者模型演示,接着阐述了Java线程池的使用,包括固定线程池的创建和销毁。此外,深入浅出地讲解了Lambda表达式及其在函数式接口中的应用,以及File类的操作,包括路径处理、I/O流读写和Properties集合的使用。
摘要由CSDN通过智能技术生成

一.线程间的通信

理解:利用等待(wait)和唤醒(notify)机制,让多个线程之间达到协同合作的目的
注意:等待(wait)唤醒(notify) 都必须被锁对象调用
等待和唤醒案例(生产者和消费者)
共享资源(包子类)
生产者线程(包子铺)
消费者线程(顾客)

二.线程池

JDK1.5之后就提供了线程池,方便执行线程任务

//第一步:获取线程池对象
	ExecutorService service=Executors.newFixedThreadPool(2); //包含2个线程的线程池
	//第二步:提交线程任务
	service.submit(new Runnable(){
		@Override
		public void run(){
			System.out.println(Thread.currentThread().getName()+"线程任务执行了");
		}
	});
	service.submit(new Runnable(){
		@Override
		public void run(){
			System.out.println(Thread.currentThread().getName()+"线程任务执行了");
		}
	}); 
	//第三步:销毁线程池(不建议),线程池就没有用了。
	service.shutdown();

三、Lamdba表达式

函数式接口:
只能有一个抽象方法的接口,但是可以有其他方法。
@FunctionalInterface 标记接口为函数式接口
使用Lamdba表达式的前提
1)必须要有一个函数式接口
2)Lambda表达式可以理解为函数式接口的实例实现(可以有效优化匿名内部类代码的冗余)
Lamdba表达式的格式
//标准格式
(Type1 param1,Type2 param2)->{… return 返回值;}
//省略数据类型
(param1,param2)->{… return 返回值;}
//省略{}以及return语句。 【如果语句体只有一条语句】
(param1,param2)-> 语句体;
//省略() 【如果参数只有一个,才能省略()】
param1-> 语句体;

Lamdba表达式的使用步骤

1)需要先有一个函数式接口
2)写一个方法,把函数式接口作为方法的参数
3)调用方法,传递的实际参数对函数式接口进行实现

**函数式接口实现方式一:**使用匿名内部类(代码冗余)
**函数式接口实现方式二:**使用Lamdba表达式(减少代码冗余)

//1)需要先有一个函数式接口
@FunctionalInterface
public interface Plant{
    public abstract void PlantFood();
}

//写一个测试类
public class Demo1{
    public static void main(String[] args){
        //3)调用方法,匿名内部类对函数式接口进行实现
        invokePlant(
            new Plant(){
                public void PlantFood(){
                    System.out.println("种玉米");
                }
            }
        );
        
        //3)调用方法,Lamdb表达式对函数式接口进行实现
        invokePlant(
            ()->{
                System.out.println("种土豆");
            }
        ); 
    }
    //2)写一个方法,把函数式接口作为方法的参数
    public static void invokePlant(Plant plant){
        plant.PlantFood();
    }
}

lambda表达式就是简化匿名内部类的写法
上面时候用到匿名内部类并要复写里面的方法,就可以考虑使用lambda表达式来简化

四.File类

理解:File类表示【文件】或者【文件夹/目录】
绝对路径和相对路径
绝对路径:从盘符开始的路径
相对路径:相对于项目的根目录,之后的路径

File构造方法

public File(String path)
根据路径创建File对象
public File(String parent,String child)
根据父路径和子路径创建File对象
public File(File parent,String child)
根据父路径和子路径创建File对象

【注意:创建File对象时候,必须指定路径(可以是存在的,也可以不存在; 可以绝对路径,也可是相对路径)】

File类的判断功能

boolean exists()
  判断File对象的路径是否存在
  boolean isDirectory()
     判断File对象的路径是否问文件夹
     如果路径不存在,返回false
  boolean isFile()
     判断File对象的路径是否问文件
     如果路径不存在,返回false
  boolean isHidden()
     判断File对象表示的文件/文件夹是否隐藏
  boolean canWrite()
     判断文件是否可写(是否只读)

File创建和删除功能

boolean createNewFile()  
创建File对象表示路径的文件
boolean mkdir() 
	创建File对象表示路径的文件夹(目录),单级文件夹
boolean mkdirs()  
	创建File对象表示路径的文件夹(目录),多级文件夹
boolean delete() 
	删除File对象表示的文件或者文件夹(必须是空文件夹)

File获取功能

String getName()
获取文件/目录的名称
File getAbsoluteFile() 
         获取绝对路径。返回File类型 
String getAbsolutePath() 
	获取绝对路径。 返回String类型
String getPath()  
	获取File对象,封装的路径
String getParent() 
	获取File对象表示文件/文件夹的父路径
long length()
	获取文件的大小(单位:字节)
	注意:文件夹的大小不能用该方法

File获取功能

String getName()
获取文件/目录的名称
File getAbsoluteFile() 
         获取绝对路径。返回File类型 
String getAbsolutePath() 
	获取绝对路径。 返回String类型
String getPath()  
	获取File对象,封装的路径
String getParent() 
	获取File对象表示文件/文件夹的父路径
long length()
	获取文件的大小(单位:字节)
	注意:文件夹的大小不能用该方法

遍历功能

File[] listFiles() 
获取一个文件夹里面的子文件/子目录。反回File[]
String[] list() 
获取一个文件夹里面的子文件/子目录。返回String[]

文件夹的遍历

public static void main(String[] args){
		printAllFile(new File("C:\\abc"));
	}
	//遍历文件夹所有的文件
	public static void printAllFile(File dir){
		//获取dir目录中所有的文件和文件夹
		File[] files=dir.listFiles();
		//遍历files数组
		for(File f:files){
			//判断f是否为文件
			if(f.isFile()){
				System.out.println(f);
			}
			//否则f就是文件夹
			else{
				printAllFile(f);
			}
		}
	} 
	//文件过滤器
	public static  void getJavaFile(File dir){
        //获取dir所有的.java文件
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if (pathname.isFile()) {
                    //如果文件名后缀为.java
                    if (pathname.getName().toLowerCase().endsWith(".java")) {
                        return true; //过滤通过
                    }else{
						//不是.java的文件
						return false; 
					}
                } else {
					//文件夹也过滤通过
                    return true;
                } 
            }
        });
        //遍历files数组
        for (File file : files) {
            if(file.isFile()){
                System.out.println(file);
            }else{
                getJavaFile(file);
            }
        }
    }

五.IO流

理解:IO流是用来读写数据的

1.按照流向分类
输入流:硬盘(文件)–>内存(Java程序)
输出流:内存(Java程序)–>硬盘(文件)

2.读写数据分类
字节流:可以读写任何数据(文本、图片、声音、视频…)
InputStream(字节输入流)
OutputStream(字节输出流)

字符流:只能读写文本数据(使用记事本软件打开能看懂的文件,就是文本文件)
Reader(字符输入流)
Writer(字符输出流)

3.使用流的步骤
1)创建流对象
2)读/写数据
3)释放资源

字节流

1.字节输出流写数据

	//1)创建字节流对象,关联一个文件
		//注意:文件不存在,会自动创建;如果文件存在,会覆盖原来的文件。
		FileOutputStream fos=new FileOutputStream("code\\a.txt");
		//2)写数据
		//一次写一个字节数据
		fos.write(97); //a
		fos.write(98); //b
		fos.write(99); //c
		fos.write(100); //d
		fos.write("\r\n".getBytes()); //换行
		//一次写多个字节数据(字节数组)
		byte[] bs={97,98,99,100};
		fos.write(bs); //abcd
		//一次写字节数组的一部分
		fos.write(bs,1,2); //bc
		//利用字节流写一个字符串(把字符串转换为字节数组)
		fos.write("helloworld".getBytes());
		fos.write("\r\n".getBytes()); //换行
		fos.write("Java".getBytes());
		//3)释放资源
		fos.close(); 

2.字节输入流读数据

	//1)创建输入流对象,关联读取的文件路径
        //注意:文件必须存在,才能读取
        FileInputStream fis=new FileInputStream("code\\a.txt");
        //2)读数据 一次读多个字节 
        byte[] bs=new byte[1024];  
        int len; //记录每次读取的有效字节个数 
        while((len=fis.read(bs))!=-1){
            //把有效的字节个数,转换为字符串
            String str=new String(bs,0,len); 
            System.out.println(str);
        }
        //3)释放资源
        fis.close(); 

3.字节流文件复制

		//源文件:day09-code\\a.txt
        FileInputStream fis=new FileInputStream("code\\a.jpg");
        //目标文件:daoy-code\\b.txt
        FileOutputStream fos=new FileOutputStream("code\\b.jpg");
        //一边读一边写
        byte[] bs=new byte[1024];
        int len; //记录每次读取的有效字节个数
        while ((len=fis.read(bs))!=-1){
            //把得到的字节中有效的部分,写到文件中
            fos.write(bs,0,len);
        }
        //释放资源
        fis.close();
        fos.close(); 

字符流

由于字节流读取数据是【以字节为单位】,由于中文和字母占用的字节数不一样,可能会出现乱码。
所以Java给开发者提供了字符流,专门用来读取文本文件,【以字符为单位】来读取数据。
Reader父类(抽象)
–InputStreamReader(转换流)
–FileReader(读取文本中的字符,默认按照UTF-8编码进行读取)
Writer父类(抽象)
–OutputStreamWriter(转换流)
–FileWriter(写入字符数据,默认按照UTF-8编码进行写入)

1.字符流读取文本文件

		//1)创建输入流对象,关联读取的文件路径
        //注意:文件必须存在,才能读取
        FileReader fr=new FileReader("code\\a.txt");

        //2)读数据) 一次读多个字符
        char[] bs=new char[1024];
		
        int len; //记录每次读取的有效字符个数
        while((len=fr.read(bs))!=-1){
            //把有效的字符个数,转换为字符串
            String str=new String(bs,0,len); 

            System.out.println(str);
        }
        //3)释放资源
        fr.close(); 

2.字符流写入文本文件

//1)创建FileWiter流对象
        //true: 表示在文件末尾续写
        FileWriter fw=new FileWriter("code\\b.txt",true);
        //2)写数据
        //直接写入字符串
        fw.write("奔驰\r\n");
        fw.write("\r\n");
        fw.write("宝马\r\n");
        //写入真个字符数组
        char[] chs={'a','b','c','车','水','马','龙'};
        fw.write(chs);
        fw.write("\r\n");
        //写入字符数组的一部分
        fw.write(chs,1,5);
		fw.flush(); //把数据刷新到文件中
        //3)释放资源
        fw.close(); //先自动刷新,再释放资源

3.字符流复制文件

//源文件:code\\a.txt
		FileReader fr=new FileReader("code\\a.txt");
		//目标文件: day09-code\\b.txt
		FileWriter fw=new FileWriter("code\\b.txt");
		
		//读写数据
		char[] chs=new char[1024];
		int len; //记录每次读取的有效字符个数
		while((len=fr.read(chs))!=-1){
			//写入有效字符个数到文件
			fw.write(chs,0,len);
		}

		//释放资源
		fr.close();
		fw.close();

Properties集合

Properties的继承结构 Map(接口) –HashMap –Hashtable –Properties

Properties也是一个双列集合,键和值都只能是字符串类型 Map集合有的方法,Properties都可以使用。

Properties还有一些特有的方法 String getProperty(String key) 获取根据键获取值 Object
setProperty(String key, String value) 往集合中添加键和值。 注意:如果键重复,返回被覆盖的值

void store(OutputStream out, String comments) 把集合中的键值对,存储到文件中

void load(InputStream inStream) 把文件中的键值对,读取到集合中

Java的基础先总结到这,之前为了赶进度也是东看看西看看,也没有一边学一边写博客。
这篇也是草草赶出来的。下周应该边学边写博客才对。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值