0
点赞
收藏
分享

微信扫一扫

Java常用类的使用

janedaring 2022-09-13 阅读 216

Java常用类

1. Optional

image-20220831233206208

反面示例:

interface IMessage{
    void echo(String msg);
}
class Factory{
    public static IMessage getInstance1(){
        return (msg -> System.out.println("msg = " + msg)); // 正常
        
    }
}
public class Demo {
    public static void main(String[] args) {
        IMessage message = Factory.getInstance1();
        if(message!=null){ // 不为null才调用
            message.echo("你好,小弟弟");
        }
    }
}

image-20220901231635533

正面示例:

interface IMessage {
    void echo(String msg);
}

class Factory {
    public static Optional<IMessage> getInstance2() {
        return Optional.of((msg -> System.out.println(msg))); // 保存到 Optional中 如果保存的为null的话,还是会发生空指针异常
    }
}

public class Demo {
    public static void main(String[] args) {
        IMessage message = Factory.getInstance2().get();// 取出 Optional中的数据
        message.echo("你好,小弟弟");
    }
}

2. ThreadLocal

1. 常用方法

image-20220901124936453

2. ThreadLocal怎么用?

下面我先举一个反面例子,加深大家的理解。

@Data
class Message {
    public String content;
}
class MessagePrint { // 输出结果
    public static void print() {
        System.out.println("【MessagePrint】" + Resource.message.content);
    }
}

/**
 * 中间类
 */
class Resource {
    static Message message;
}
/**
 * 测试
 * @author jiejie
 * @date 2022/09/01
 */
public class Demo1 {
    public static void main(String[] args) {
        String[] values = {"你好,弟弟", "你好,妹妹", "你好,姐姐"};
        for (String value : values) {
            new Thread(() -> {
                Resource.message = new Message();
                Resource.message.setContent(value);
                MessagePrint.print();
            }).start();
        }
    }

结果:

image-20220901124138229

修改Resource:

/**
 * 中间类
 */
class Resource {
	
    private static ThreadLocal<Message> threadLocal = new ThreadLocal<>();

    public static Message getMessage() {
        return threadLocal.get();
    }

    public static void setMessage(Message message) {
        threadLocal.set(message);
    }

    public static void removeMessage() {
        threadLocal.remove();
    }
}
class MessagePrint { // 输出

    public static void print() {
        System.out.println("【MessagePrint】" + Resource.getMessage().content);
    }
}
public class Demo1 {
    public static void main(String[] args) {
        String[] values = {"你好,弟弟", "你好,妹妹", "你好,姐姐"};

        for (String value : values) {
            new Thread(() -> {
                    Resource.setMessage(new Message());
                    Resource.getMessage().setContent(value);
                    MessagePrint.print();
            }).start();
        }
    }
}

程序执行结果:

image-20220901124719338

3. 定时任务

image-20220902103135845

1. timer

简单用法

public class Demo {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("【定时任务】定时执行");
            }
        }, 1000, 2000);
    }
}

执行结果:

【定时任务】定时执行
【定时任务】定时执行
【定时任务】定时执行

1.2 schedule和scheduleAtFixedRate有什么区别?

1.3:如果执行task发生异常,是否会影响其他task的定时调度?

1.4 Timer的一些缺陷?

2 JDK对定时任务调度的线程池支持:ScheduledExecutorService

我们直接看例子:

image-20220902125525163

执行结果:

3 定时任务大哥:Quartz

3.1 核心:

任务 Job

触发器 Trigger

调度器 Scheduler

3.2 使用Quartz

导入依赖:

		<!--quartz-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
        </dependency>

创建任务类:

public class TestJob implements Job{

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("【定时任务】定时执行"+new Date());
    }
}

测试

class TestScheduler {
    public static void main(String[] args) throws SchedulerException {
        // 获取默认任务调度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        // 定义Job(任务)实例
        JobDetail testJob = JobBuilder.newJob(TestJob.class)
                .withIdentity("测试任务").build();
        // 定义触发器
        Trigger simpleTrigger = TriggerBuilder.newTrigger()
                .withIdentity("测试任务的触发器")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1))
                .build();
        // 使用触发器调度任务的执行
        scheduler.scheduleJob(testJob, simpleTrigger);
        scheduler.start();
    }
}

image-20220902132836415

经过上面的简单使用,我们再来了解下它的结构吧

image-20220902153106561

图中可知,还有一种触发器 CronTrigger,下面简单使用一下吧。

Cron表达式用法

测试类 任务类不变,修改测试类即可

class TestScheduler {
    public static void main(String[] args) throws SchedulerException {
        // 获取默认任务调度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        // 定义Job(任务)实例
        JobDetail testJob = JobBuilder.newJob(TestJob.class)
                .withIdentity("测试任务").build();
        // 定义触发器
        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity("name", "group")
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * ? * *")).build();
        // 使用触发器调度任务的执行
        scheduler.scheduleJob(testJob, cronTrigger);
        scheduler.start();
    }
}

4 Arrays

常用方法:

image-20220902195539079

1 排序

public class Demo {
    public static void main(String[] args) {
        int[] arr = {1, 2, 19, 4, 5, 6, 7, 8, 9};
        System.out.printf("【未排序前的数组:】%s \n", Arrays.toString(arr)); // Arrays.toString(arr) 数组转换成字符串
        Arrays.sort(arr);
        System.out.printf("【排序后的数组:】%s", Arrays.toString(arr));
    }
}
// 执行结果
//【未排序前的数组:】[1, 2, 19, 4, 5, 6, 7, 8, 9] 
//【排序后的数组:】[1, 2, 4, 5, 6, 7, 8, 9, 19]

2 判断是否相等

public class Demo2 {
    public static void main(String[] args) {
        int[] arrA = {1, 5, 7};
        int[] arrB = {7, 5, 1};
        System.out.println("【判断是否相等 -未排序】" + Arrays.equals(arrA, arrB));
        Arrays.sort(arrA);
        Arrays.sort(arrB);
        System.out.println("【判断是否相等 -排序后】" + Arrays.equals(arrA, arrB));
        
        System.out.println("【判断数组的大小关系 -排序后】" + Arrays.compare(arrA, arrB));
        System.out.println("【判断数组的大小关系 -随机数组】" + Arrays.compare(new int[]{1, 2, 3}, arrB));
        System.out.println("【判断数组的大小关系 -随机数组】" + Arrays.compare(new int[]{7, 8, 9}, arrB));
    }
}
// 执行结果
//【判断是否相等 -未排序】false
//【判断是否相等 -排序后】true
//【判断数组的大小关系 -排序后】0
//【判断数组的大小关系 -随机数组】-1
//【判断数组的大小关系 -随机数组】1

3 二分查找

public class Demo3 {
    public static void main(String[] args) {
		int[] arrA = {1, 3, 5, 7, 9};// 模拟数组
        int key = 9;// 需要查找的数据
        int index = search(arrA, key);
        System.out.println("index = " + index);
    }
	
    // 普通 循环查询,未查找到返回-1
    private static int search(int[] arrA, int key) {
        for (int i = 0; i < arrA.length; i++) {
            if (arrA[i] == key) {
                return i;
            }
        }
        return -1;
    }
}

然后我们再来看看,二分查找。

   /**
     * 二分查找
     */
    private static int twoPoints(int[] arrA, int key) {
        Arrays.sort(arrA);
        System.out.println("【排序后的数组:】"+Arrays.toString(arrA));
        // 开始索引
        int start = 0;
        // 结束索引
        int end = arrA.length - 1;
        while (start <= end) {
            // 位运算 这里以5为例 101(5) >>>1 10(2) mid(中间的下标)
            int mid = start+end >>> 1;
            int midVal = arrA[mid];
            // 用中间值的key比较,中间值小的话,说明我们需要查找的数据在右边,中间值+1赋值start
            if (midVal < key) {
                start = mid + 1;
            }// 用中间值的key比较,中间值打的话,说明我们需要查找的数据在右边,中间值-1赋值end
            else if (midVal > key) {
                end = mid - 1;
            } else {
                return mid;
            }
        }
        // 未找到
        return -1;
    }

image-20220902215515188

4 比较器

4.1 比较器出现的原因

public static void sort(Object[] a) 
@AllArgsConstructor
@Data
class Book{
    String name;
    double price;
}
public class 比较器 {
    public static void main(String[] args) {
       Book[] books= new Book[] {
               new Book("Java入门到入土",89.0),
               new Book("Python入门到入土",78.0),
           	   new Book("前端入门到入土",68.0)
       };
        Arrays.sort(books);
    }
}

执行程序: 可以发现,程序执行报错了。类转换异常

Exception in thread "main" java.lang.ClassCastException: class look.word.arrays.Book cannot be cast to class java.lang.Comparable (look.word.arrays.Book is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
	at java.base/java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
	at java.base/java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
	at java.base/java.util.Arrays.sort(Arrays.java:1041)
	at look.word.arrays.比较器.main(比较器.java:26)

4.2 Comparable

示例:

@AllArgsConstructor
@Data
class Book implements Comparable<Book>{
    String name;
    double price;
    
    @Override
    public int compareTo(Book book) {
        if (this.price > book.price){
            return 1;
        } else if (this.price < book.price) {
            return -1;
        }
        return 0;
    }
}

执行程序:

【Book类继承比较器比较后的结果】
 [Book(name=前端入门到入土, price=68.0), 
 Book(name=Python入门到入土, price=78.0),
 Book(name=Java入门到入土, price=89.0)]

4.3 Comparator

image-20220903093113311

示例代码:

@AllArgsConstructor
@Data
class books {
    String name;
    double price;
}
public class 比较器2 {
    public static void main(String[] args) {
        books[] books = new books[]{
                new books("Java入门到入土", 89.0),
                new books("Python入门到入土", 78.0),
                new books("前端入门到入土", 68.0)
        };
        Comparator<books> comparator = (books1, books2) -> {
            if (books1.price > books2.price) {
                return 1;
            } else if (books1.price < books2.price) {
                return -1;
            }
            return 0;
        };
        Arrays.sort(books, comparator.reversed()); //  comparator.reversed() 是反转的意思
        System.out.println("【books类继承比较器比较后的结果】\n" + Arrays.toString(bookss));
    }
}

程序执行结果:

【books类继承比较器比较后的结果】
[books(name=Java入门到入土, price=89.0), 
 books(name=Python入门到入土, price=78.0), 
 books(name=前端入门到入土, price=68.0)]

5 StringBuffer

传统面向过程做法

/**
 * 传统面向过程实现
 **/
public class Demo {
    public static void main(String[] args) {
        StringBuffer buffer = new StringBuffer(26);
        for (int i = 'a'; i <= 'z'; i++) {
            buffer.append((char) i);
        }
        System.out.println("【初始的数据】" + buffer);
        System.out.println("【逆序输出】" + buffer);
        System.out.println("【删除前5个】" + buffer.delete(0, 5));
    }
}

**范例:**通过面向对象的方式进行程序的开发

interface IContent { // 接口先行
    String content();
    String reverse();
    String delete(int start, int end);
}

class StringContent implements IContent {
    private StringBuffer buffer = new StringBuffer(26);
    public StringContent() {
        for (int i = 'a'; i <= 'z'; i++) {
            buffer.append((char) i);
        }
    }
    public String content() {
        return buffer.toString();
    }
    public String reverse() {
        return buffer.reverse().toString();
    }
    public String delete(int start, int end) {
        return buffer.delete(start, end).toString();
    }
}
class Factory { // 工厂获取实例
    private Factory() {}
    public static StringContent getInstance() {
        return new StringContent();}
}
public class Demo2 {
    public static void main(String[] args) {
        StringContent content = Factory.getInstance();
        System.out.println("【初始的数据】" + content.content());
        System.out.println("【逆序输出】" + content.reverse());
        System.out.println("【删除前5个】" + content.delete(0, 5));
    }
}

6 反射

1. 出现的原因

范例:观察传统的类的使用行为

class Book{
    public void read(){
        System.out.println("认真学习java书籍!");
    }
}

public class Demo {
    public static void main(String[] args) {
        Book book = new Book(); // 实例化对象
        book.read(); // 调用实例的方法
    }
}
// 执行结果: 认真学习java书籍!

2. 反射的入口

java.lang.Class

获取类Class对象的四种方式:

  • 调用运行时类本身的.class属性
Class<String> stringClass = String.class;
  • 通过运行时类的对象获取
 Class<? extends String> aClass = new String().getClass();
  • 通过Class的静态方法获取:体现反射的动态性
		try {
            Class<?> aClass1 = Class.forName("java.lang.String");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
  • 通过类的加载器
		ClassLoader classLoader = this.getClass().getClassLoader(); // 获取类加载器
        Class<?> aClass1 = classLoader.loadClass("java.lang.String");

3. 获取成员变量

@Data
class Books{
    String name;
    public Integer age;
    private Integer gender;
    protected String salt;
}
public class 属性 {
    public static void main(String[] args) {
        Class<Books> booksClass = Books.class;
        // 获取所有属性 包括私有的
        Field[] fields = booksClass.getDeclaredFields();
        for (Field field : fields) {
            // 设置访问无障碍
            field.setAccessible(true);
            System.out.print("【修饰符】" + Modifier.toString(field.getModifiers()));
            System.out.print("【\t变量的类型】" + field.getType());
            System.out.print("【\t属性的的名称】 = " +  field.getName()+"\n");
        }
    }
}

4. 调用方法

class Book1 {
    public void init() {
        System.out.println("初始图书" );
    }
    public void read(String name) {
        System.out.println("读了" + name);
    }
}
public class 方法 {
    public static void main(String[] args) throws Exception {
        Class<Book1> bookClass = Book1.class; // 获取Class对象
        Method init = bookClass.getMethod("init"); // 获取指定方法
        init.invoke(bookClass.newInstance(),null); // 执行实例无参方法
        Method read = bookClass.getMethod("read", String.class); // 获取指定方法
        read.invoke(bookClass.newInstance(),"java图书"); // 执行实例有参方法
        Method[] methods = bookClass.getMethods();
        for (Method method : methods) { // 遍历所有方法
            System.out.println("method = " + method);
        }
    }
}
举报

相关推荐

0 条评论