一.线程间的通信
理解:利用等待(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的基础先总结到这,之前为了赶进度也是东看看西看看,也没有一边学一边写博客。
这篇也是草草赶出来的。下周应该边学边写博客才对。