线程池:
在多线程的使用过程中,会存在一个问题:如果并发的线程数量很多,并且每个线程都执行一个时间很短的任务就结束,这样频繁的创建线程就会大大降低系统的效率,因为线程的创建和销毁都需要时间。
线程池: 为了解决上面频繁的创建和销毁线程的问题,在java中可以通过线程池来达到线程复用的场景,也就是一个线程在执行完一个任务后,不会被销毁,而是继续执行其他的任务。线程池实际就是一个容纳线程的容器,省去了频繁创建线程对象的操作,节约了很多资源。
线程池执行原理:
线程池的使用:
设置线程任务:
public class RunnableImpl implements Runnable {
@Override
public void run(){
System.out.println("线程:" + Thread.currentThread().getName());
};
}
使用过程:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// java.util.concurrent.Executors:线程池的工厂类,用来生成线程池,其中有一个方法用来生成一个指定线程数的线程池:newFixedThreadPool(int n)
// 线程池的使用步骤:
// 1.使用线程池的工厂类:Executors里的静态方法newFixedThreadPool创建一个指定线程的线程池
// 2.创建一个类,实现Runnable接口,重写run方法设置线程任务
// 3.调用ExecutorService中的submit方法,传递线程任务(刚刚创建的实现类)开启线程
// 4.调用ExecutorService中的shutdown销毁线程池(不建议使用,只有线程池不需要的时候才会用到该方法)
public class ThreadPool {
public static void main(String[] args) {
// 获取线程池:
ExecutorService es = Executors.newFixedThreadPool(2); // 指定线程池数量
// 执行线程任务:线程池会一直开着,使用完了线程,会自动把线程归还给线程池,线程可以继续执行
es.submit(new RunnableImpl()); // 线程:pool-1-thread-1
// es.shutdown(); // 执行此代码关闭线程池,后面代码在执行会抛异常
es.submit(new RunnableImpl()); // 线程:pool-1-thread-2
es.submit(new RunnableImpl()); // 线程:pool-1-thread-1,第一次使用完后会归还给线程池继续被使用
}
Lambda表达式:
Lambda表达为了解决冗余代码问题的,从创建一个多线程任务的案例来看,为了执行run任务,是不断的调用对象的方法,此过程为面向对象编程,为了执行一个run任务(打印一句话)发现写了很多无关的代码,但是这些代码在面向编程中又不能没有,此时为了简化代码书写减少代码冗余,可以采用函数式编程,函数式编程是一个只注重结果,不注重是谁完成了这个事,Lambda就是函数式编程思想。
Lambda表达式由三部分组成:一些参数、一个箭头、一段代码
import java.util.Arrays;
import java.util.Comparator;
public class LambdaTest {
public static void main(String[] args){
// 1.测试lambda表达式:
// 使用匿名内部类创建一个线程任务:
new Thread(new Runnable(){
@Override
public void run(){
System.out.println("执行任务!");
};
}).start();
// 使用Lambda创建一个线程任务:
new Thread(()->{
System.out.println("执行Lambda任务!");
}).start();
// Lambda更优写法:其中括号为run方法的参数,可以接收前面需要传递的参数,箭头表示将参数传递给后面,箭头后面的语句为业务逻辑代码
new Thread(()->System.out.println("执行Lambda任务2!")).start();
// 2.调用useSayHayInterFace方法:
useSayHayInterFace(new SayHay(){
@Override
public void sayhello(){
System.out.println("重写sayhello方法");
};
});
// 3.使用lambda表达式调用useSayHayInterFace方法:
useSayHayInterFace(()->System.out.println("重写sayhello方法2"));
// 4.使用lambda表达式联系一个数组中存储多个person对象,并对其以年龄进行排序:
Person[] list = { new Person("小明",18), new Person("小红",20),new Person("小美",10) };
Arrays.sort(list, new Comparator<Person>(){
@Override
public int compare(Person a,Person b){
return a.getAge() - b.getAge();
};
});
for (Person p : list) {
System.out.println(p);
};
System.out.println("----------------------------");
// 使用lambda表达式简化:
Arrays.sort(list, (Person a,Person b)->{
return b.getAge() - a.getAge();
});
for (Person p : list) {
System.out.println(p);
};
};
// 定义一个方法使用接口:
public static void useSayHayInterFace(SayHay s){
s.sayhello();
};
}
file类:
file类是文件和目录路径名的抽象表示,主要用于文件和目录的创建和查找及删除等操作。
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
public class FileDemo {
// 1.file类可以创建一个文件或文件夹、删除一个文件或文件夹、获取一个文件或文件夹
// 2.file类与操作系统无关,任何操作系统都可以使用此类
public static void main(String[] args) throws IOException {
// 3.File类的pathSeparator属性用来获取路径分隔符
String pathSeparator = File.pathSeparator;
System.out.println(pathSeparator); // 打印了一个封号,windows分隔符是一个分号,linux会打印一个冒号
// 4.File类的separator属性用来获取文件名分隔符:
String separator = File.separator;
System.out.println(separator); // 打印了一个反斜杠,windows返回一个反斜杠,linux返回一个正斜杠
// 5.路径:分绝对路径和相对路径,相对路径是相对于当前项目的根目录,绝对路径是相对于盘符开始的,路径不区分大小写,windows中文件名分隔符为反斜杠,需要写两个反斜杠进行转义。
// 6.File类的构造方法:此构造方法传入一个路径,用来创建一个新的File实例,这个路径可以是以文件名结尾,也可以以文件夹结尾,也可以是一个不存在的路径
File fs = new File("D:\\00.java高级\\练习\\javaDemo\\073file类");
System.out.println(fs); // D:\00.java高级\练习\javaDemo\073file类
// file类的构造方法也可以传递两个参数:第一个父路径,第二个为子路径:实际就是将两个路径进行拼接在一起:
File fs2 = new File("c://","a.text");
System.out.println(fs2); // c:\a.text
// file类的第一个参数父路径也可以传入一个file类:
File fs3 = new File(fs, "b.text"); // 这里的父类路径后面可以调用它的方法得到想要的值:
System.out.println(fs3); // D:\00.java高级\练习\javaDemo\073file类\b.text
// 7.getAbsoluteFile()方法用来获取File类的绝对路径,String.valueOf是这个java版本中结局报错的
File fs4 = new File("ab.text");
String p3 = String.valueOf(fs4.getAbsoluteFile());
System.out.println(p3); // D:\00.java高级\练习\javaDemo\073file类\ab.text
// 8.getPath方法获取File类的真实路径,传递的什么,返回的就是什么:
File fs5 = new File("D://files//hello.text");
String p5 = fs5.getPath();
System.out.println(p5); // D:\files\hello.text
File fs6 = new File("hello.text");
String p6 = fs6.getPath();
System.out.println(p6); // hello.text
// 9.getName方法获取File类的结尾部分,可以是一个文件夹或文件名:
String fsname = fs.getName();
System.out.println(fsname); // 073file类
String fileName = fs5.getName();
System.out.println(fileName); // hello.text
// 10.length获取文件的大小,以字节为单位:如果路径不存在,则返回0,文件夹返回的也是0
File fslength = new File("D:\\00.java高级\\练习\\javaDemo\\073file类\\FileDemo.java");
Number sizes = fslength.length();
System.out.println(sizes); // 3261
// 11.exists方法用来判断File表示的文件或路径是否存在:
File isExist = new File("hello.java");
System.out.println(isExist.exists()); // false
// 12.isDirectory判断给定的路径是否以文件夹结尾,isFile判断给定的目录是否以文件结尾:(特别提示:这个两个方法都是建立在路径真实存在的情况下,如果不存在则都表示false)
System.out.println(fs.isDirectory()); // true
System.out.println(fs.isFile()); // false
System.out.println(isExist.isFile()); // false
System.out.println(isExist.isDirectory()); // false
System.out.println(fslength.isFile()); // true
System.out.println(fslength.isDirectory()); // false
// 13.createNewFile()方法用来创建文件,如果File类没有此文件就去创建文件并返回一个true,如果已存在文件再去创建,会返回false;创建文件的路径必须存在,否则会抛出异常:
File ft = new File("D:\\00.java高级\\练习\\javaDemo\\073file类\\hello.text"); // 路径是相对或绝对都可以
boolean file1 = ft.createNewFile(); // 此方法或抛出异常,可以使用try/cathc或直接抛出给虚拟机处理
System.out.println(file1); // true,第一次执行返回一个true并生成一个hello.text文件,再次执行代码就返回false,因为已经存在了此文件
// 14.mkdir和mkdirs用来创建文件夹,mkdir用来创建单级文件夹,mkdirs用来创建多级文件夹,它们创建的都是空文件夹,如果原本文件夹不存在去创建返回true,原本文件夹存在或路径不存在都返回false,它们只能创建文件夹,不能创建文件,绝对和相对路径都支持,路径不存在不会抛异常:
File fp = new File("D:\\00.java高级\\练习\\javaDemo\\073file类\\newfile1");
boolean isOk = fp.mkdir();
System.out.println(isOk); // true,也是第一次返回true,再次执行返回false
File fm = new File("D:\\00.java高级\\练习\\javaDemo\\073file类\\newfile2\\001\\01\\1");
boolean isOkMor = fm.mkdirs(); // 创建多级文件夹
System.out.println(isOkMor); // true,也是第一次返回true,再次执行返回false
// 15.delete方法可以删除文件或文件夹,文件或文件夹删除成功返回true,文件夹中有内容时不会被删除返回false,构造方法中的路径不存在时也返回false(在硬盘中删除,不走回收站)
File rm = new File("D:\\00.java高级\\练习\\javaDemo\\073file类\\hello.text");
boolean isRm = rm.delete();
System.out.println(isRm); // true
File rm2 = new File("D:\\00.java高级\\练习\\javaDemo\\073file类\\newfile2\\001\\01\\1");
boolean isRm2 = rm2.delete();
System.out.println(isRm2); // true,这里删除的1这个文件夹,需要注意!
// 16.list和listFiles方法用来遍历目录,list返回一个字符串数组,表示该文件夹中所有子文件或子文件夹;listFiles返回的是一个文件类型数组,如果构造方法中的路径不存在,会抛出异常,如果构造方法中的路径不是一个目录,也会抛出异常
File fslist = new File("D:\\00.java高级\\练习\\javaDemo\\073file类");
String[] ls = fslist.list();
System.out.println(Arrays.toString(ls));
System.out.println("-----1------");
for (String s : Objects.requireNonNull(ls)) {
System.out.println(s);
}
File[] flist = fslist.listFiles();
System.out.println(Arrays.toString(flist));
System.out.println("-----2------");
for (File f : Objects.requireNonNull(flist)) {
System.out.println(f);
}
}
}
递归:
java中递归是指方法的自调用,递归可分为直接递归(直接调佣自己)和间接递归(在a方法中调用b方法,b方法中又调用了a方法);递归中应该有条件限制和次数不能太多,否则容易导致栈溢出,递归应该有结束条件。
过滤规则:
import java.io.File;
import java.io.FileFilter;
public class FileFilterImpl implements FileFilter {
// 1.实现一个FileFilter接口并重写接口中的accept方法实现过滤规则:
@Override
public boolean accept(File pathname){
// 返回true会放过这个值,返回false会过滤掉:
if (pathname.isDirectory()) {
// 如果是文件夹也返回true继续遍历
return true;
}
return pathname.getName().toLowerCase().endsWith(".java");
};
}
递归测试:
import java.io.File;
import java.util.Objects;
public class ForMethods {
public static void main(String[] args){
// 1.实现递归:
int num = 0;
count(num);
// 2.过滤器:listFiles方法有两个重载形式,里面传入一个FileFilter接口的实习类对象可对目录项进行过滤:
File fslist = new File("D:\\00.java高级\\练习\\javaDemo\\074.递归");
// 传入FileFilter接口的实现类对象进行过滤数据
File[] flist = fslist.listFiles(new FileFilterImpl());
for (File f : Objects.requireNonNull(flist)) {
// System.out.println(f);
}
// 3.过滤器找到所有的java结尾的文件:
File fs = new File("D:\\00.java高级\\练习\\javaDemo\\074.递归");
getAllFile(fs);
}
public static void count(int i){
if (i > 10) { // 结束条件,递归的次数不能太多,否则会有栈溢出
return;
} else {
// System.out.println(i);
i++; // 改变条件变量
count(i);
}
};
//3.递归的方式打印出以java结尾的文件:
public static void getAllFile(File dir){
File[] files = dir.listFiles(new FileFilterImpl());
for (File f : Objects.requireNonNull(files)) {
// 如果是目录则继续递归遍历,否则打印文件名
if (f.isDirectory()) {
getAllFile(f);
System.out.println("继续递归:" + f);
} else {
System.out.println(f);
}
}
};
}
提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:810665436@qq.com联系笔者删除。
笔者:苦海