Java基础

Java 三大特性

封装 + 继承 + 多态

什么是面向对象?

面向对象是一种编程思想,是面向过程思想的衍生,将复杂的事情简单化,将我们从事情的执行者变成指挥者

在java中我们可以将任何事务看成一个对象 ,其有三大特征封装 + 继承 + 多态

1. 封装: 隐藏对象的内部特性和行为

好处:  
· 保护内部的状态。
· 禁止对象之间的不良交互提高模块化
· 对象的行为可以被单独的改变或者是扩展,提高了代码的可用性和可维护性。

2. 继承: 从基类(父类)获取字段和方法的能力

好处:  
· 提供了代码的重用性,可以在不修改基类的情况下给现存的类添加新特性。

3. 多态: 给不同的底层数据类型做相同的接口展示

好处:  
· 一个多态类型上的操作可以应用到其他类型的值上面
重写(Overriding) 重载(Overloading)
类的数量 父子类、接口与实现类 本类
方法名称 一致 一致
参数列表 一定不能修改 必须修改
返回类型 一定不能修改 可以修改
异常 可以减少或删除,但不能扩展
重载
public void out(){
    System.out.println("参数"+null);
}
//参数数目不同
public void out(Integer n){
    System.out.println("参数"+n.getClass().getName());
}

Java 基本数据类型 包装类型

1、包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是

2、包装类型是引用的传递,基本类型是值的传递

3、声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间

4、存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们

5、初始值不同,eg: int的初始值为 0 、 boolean的初始值为false 而包装类型的初始值为 null

6、使用方式不同,基本数据类型直接赋值使用就好 ,而包装类型是在集合如 coolection Map时会使用

Java 反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制

class User{
    private Integer age = 11;
    private String name = "jack";

    public User(){
        super();
    }

    public User(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}


//-----------获取这个类
// 方法一 根据类名路径
Class user = Class.forName("com.yifan.reflex.User");
// 方法二 已知这个类
Class user = Class.forName(User.class.getName());

//-----------创建这个类的实例对象
//无参
 User user = (User) user.newInstance();
//有参
//获得构造对象
Constructor<User> constructor = user.getConstructor(Integer.class, String.class);
User hahah = constructor.newInstance(1, "hahah");

Java 多线程实现方法

1 , 继承 thread 类,重写 run 方法 ==单继承局限性==

2 , 实现 Runnable 接口,重写 run 方法 ==避免单继承局限性,灵活方便,方便同一个对象被多个线程使用==

3 , 实现 Callable 接口,重写 call 方法(有返回值,)

4 , 使用线程池

线程的5大状态

创建 —-> 就绪 —-> 堵塞 —-> 运行 —–> 死亡

Thread中, join() 方法的作用是等待调用的线程完成后,才能继续用下运行。

synchronized 锁的对象是变化的量 就是锁的共享资源

synchronized 同步方法 锁的默认是这个对象

​ public synchronized void add

synchronized 同步代码块 锁的可以是任意对象

​ synchronized(obj){}

synchronized锁的是什么

https://blog.csdn.net/djrm11/article/details/88386719?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

Java 集合

image-20210802092529651

list 有序 可以重复 链表实现 ArrayList(动态数组) 查询快 , LinkedList(双向链表) 删除插入快

set 无序 元素不允许重复,可以插入null

数组是静态 集合是动态

Array 是指定固定大小的,而 ArrayList 大小是自动扩展的。

数组 线性排列,执行效率和检查是最快

HashMap 的实现原理?

HashMap 基于 Hash 算法实现的,我们通过 put(key,value)存储,get(key)来获取。当传入 key 时,HashMap 会根据 key. hashCode() 计算出 hash 值,根据 hash 值将 value 保存在 bucket 里。当计算出的 hash 值相同时,我们称之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的 value。当 hash 冲突的个数比较少时,使用链表否则使用红黑树。

HashSet 是基于 HashMap 实现的,HashSet 不允许重复的值。

数组转 List:使用 Arrays. asList(array) 进行转换。

List 转数组:使用 List 自带的 toArray() 方法。

HashMap底层数据结构

Jdk8之前:数组+链表

Jdk8后:数组+链表+红黑树

如何复制一个Java对象(浅克隆与深度克隆)

浅克隆 : 实现 Cloneable 接口并重写 Object 类中的 clone() 方法

clone一个对象时,只clone了里面的某些属性,对象里面的对象不能被克隆出来

深克隆 : 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆

譬如Person类中有两个对象,一个是Arm,一个是Address

现在我们的需求是,克隆一个Person对象,但是不要它的Address属性,仅克隆除Address外的所有属性

我们在不想被序列化的属性上加一个关键字 transient

package com.yifan.clone;

import java.io.Serializable;

/**
 * @Author YIFan
 * @Date 2020/7/15 14:13
 * @Version 1.0
 */
public class Arm implements Serializable {

    private String armName;


    public void setArmName(String armName) {
        this.armName = armName;
    }

    public String getArmName() {
        return armName;
    }
}
package com.yifan.clone;

import java.io.*;

/**
 * @Author YIFan
 * @Date 2020/7/15 14:13
 * @Version 1.0
 */
public class Person implements Serializable {

    private Integer age;
    private String name;
    private Arm arm;

    public void setArm(Arm arm) {
        this.arm = arm;
    }

    public Arm getArm() {
        return arm;
    }

    /*
     * 深度克隆
     *
     * */

    public Object deepClone() throws IOException, ClassNotFoundException {
        // 将对象写到流里
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        ObjectOutputStream outputStream = new ObjectOutputStream(stream);
        outputStream.writeObject(this);

        // 从流里读出来
        ByteArrayInputStream inputStream = new ByteArrayInputStream(stream.toByteArray());
        ObjectInputStream iStream1 = new ObjectInputStream(inputStream);
        return iStream1.readObject();
    }


    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public String getName() {
        return name;
    }
}
package com.yifan.clone;

import java.io.IOException;

/**
 * @Author YIFan
 * @Date 2020/7/15 14:20
 * @Version 1.0
 */
public class Tset {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person person = new Person(15,"jack");
        Arm arm = new Arm();
        arm.setArmName("qweqr");
        person.setArm(arm);

        Person clone = (Person)person.deepClone();

        System.err.println("修改前------");
        System.err.println("clone --> "+clone.getArm().getArmName());
        System.err.println(clone.getName());

        System.err.println("修改后------");
        clone.getArm().setArmName("ahhhh");
        clone.setName("lucy");
        System.err.println("clone --> "+clone.getArm().getArmName());
        System.err.println("person --> "+person.getArm().getArmName());
        System.err.println(clone.getName());
    }
}

图片

数据加密算法

1,对称加密

加密解密使用同一密钥

DES,3DES,RC4,RC5,RC6,AES,IDEA

2,非对称加密

指加密和解密使用不同密钥

RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)

3,Hash算法

MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1

Java 8

Predicate接口

在这里插入图片描述

Predicate 断言

在这里插入图片描述

使用

Predicate<Integer> predicate = x -> x > 5;
Predicate<Integer> p = x -> x < 10;
System.err.println(predicate.and(p).test(8)); // true 10>8>5
System.err.println(predicate.or(p).test(11)); // true 11> 5 一真为真
System.err.println(predicate.negate().test(11)); // false 11 > 5 取反
// Predicate.isEqual方法返回的Predicate类型的test方法中的参数与targetRef做比较
System.err.println(Predicate.isEqual(1).test(1)); // true
System.err.println(Predicate.isEqual(1).test(2)); // false

对象的引用

方法引用的几种形式

  • 类名::静态方法名
  • 类名::实例方法名
  • 对象::实例方法名
  • 类型::new(构造方法的引用)

函数式接口

方法中接口作为参数的情况:

方法传递一个接口,这个接口有且只有一个方法,我们称为A方法,
B方法调用这个A方法时,这个接口参数即为这个方法参数,
可以如下简化
()->{return xxx}
箭头左边就是这个A方法需要传递的参数,右边为这个B方法返回的参数。


例如 方法中传递接口
 public static <T> T handle(Invoker<T> invoker) {
   T invoke(ReservationOperateDto obj);
 };
 
调用的方法
 public String saveHeadInfo(ReservationMerchantDto reservationMerchantDto) {
   handle( (ReservationOperateDto res)->{return "string";})
 
 }
  • Function<T, R>——接收 T,返回 R

image-20230403145621263

// 函数式接口
/**
 * @Author YIFan
 * @Date 2023-5-13 14:41
 * @Version 1.0
 */
public class FuncIfUtil {

    public static ThrowExceptionFunction isTrue(Boolean bool) {
        return message -> {
            if (!bool) throw new RuntimeException(message);
        };
    }

    public static NullBranchHandlerFunction<Object> isNull(Object obj) {
        return (trueHandler, falseHandle) -> {
            if (StringUtils.isEmpty(obj)) {
                System.err.println("为空");
                trueHandler.run();
            } else {
                System.out.println("不为空");
                falseHandle.accept(obj);
            }
        };
    }
}
@FunctionalInterface
public interface NullBranchHandlerFunction<C> {
    void isNullHandler(Runnable trueHandler, Consumer<? super C> falseHandler);
}

@FunctionalInterface
public interface ThrowExceptionFunction {
    void throwEx(String message);
    default void throwEx2(String message,String a ){};
}
public class FunTest {

    public static void main(String[] args) {

        FuncIfUtil.isTrue(false).throwEx("报错了");

        AtomicReference<String> a = new AtomicReference<>("");
        FuncIfUtil.isNull("12221").isNullHandler(() -> {
            a.set("null");
        }, (consume) -> {
            a.set(consume.toString());
        });
        System.err.println(a.get());
    }
}

CompletableFuture异步编程

1、CompletableFuture创建

CompletableFuture 对象,任务会在默认的 ForkJoinPool 中异步执行。

//该方法用于执行具有返回值的任务,并在任务完成时返回结果。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    // 执行具有返回值的任务
    return "任务结果";
});
//创建一个没有返回值的 CompletableFuture 对象
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
    // 执行没有返回值的任务
});
//获取任务结果
join() 会阻塞当前线程,直到任务完成并返回结果。
get()  会阻塞当前线程,直到任务完成并返回结果。
    与join() 方法不同的是,get() 方法会抛出InterruptedException和ExecutionException异常,需要进行异常处理。

2、异步回调方法

//然后申请   把上一个线程的结果“应用于”下一个线程的计算。相当于结果值的传递
thenApply(Function<? super T, ? extends U> fn)  //同步执行的
thenApplyAsync //异步

//输入参数:上一阶段的任务结果类型为 T。
//返回值:新阶段的任务结果类型为 U。
//功能:对上一阶段的任务结果进行转换操作,并返回一个新的 CompletableFuture 对象。
    
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42)
    .thenApply(result -> result * 2)
    .thenApply(result -> result + 1);

使用 thenApply()方法对上一阶段的结果进行转换,
    将结果乘以 2,并将转换后的结果加 1。
    每个 thenApply()方法都返回一个新的 CompletableFuture 对象,可以继续链式调用。
//然后消费 
thenAccept(Consumer<? super T> action)
    
//输入参数:上一阶段的任务结果类型为 T。
//返回值:CompletableFuture,没有返回值。
//功能:对上一阶段的任务结果进行消费操作,没有返回值。消费后,后面就获取不到这个T的结果了
    
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42)
    .thenAccept(result -> System.out.println("任务结果:" + result));
//然后运行
thenRun(Runnable action)
        
////输入参数:无。
//返回值:CompletableFuture,没有返回值。
//功能:在上一阶段任务完成后执行给定的 Runnable 任务,没有输入参数和返回值。
    
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42)
    .thenRun(() -> System.out.println("任务执行完毕"));
//然后合并
thenCombine(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn)
    
//输入参数:另一个 CompletionStage 对象和一个 BiFunction 函数,函数的输入参数分别为上一阶段的任务结果类型 T 和另一个 CompletionStage 对象的任务结果类型 U,函数的返回值类型为 V。
//返回值:新阶段的任务结果类型为 V。
//功能:当两个 CompletionStage 对象都完成时,将它们的任务结果传递给给定的 BiFunction 函数进行组合处理,并返回一个新的 CompletableFuture 对象。
//然后编写
thenCompose(Function<? super T, ? extends CompletionStage> fn)

//输入参数:一个 Function 函数,函数的输入参数为上一阶段的任务结果类型 T,函数的返回值为另一个 CompletionStage 对象。
//返回值:新阶段的任务结果类型为 U。
//功能:当上一阶段的任务完成后,将结果传递给给定的 Function 函数,该函数返回一个新的 CompletionStage 对象,新阶段的任务结果类型为 U。
    
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);

CompletableFuture<Integer> future2 = future1.thenCompose(result -> CompletableFuture.supplyAsync(() -> result * 2));
//所有都执行完
allOf(CompletableFuture<?>... cfs)
    
//输入参数:多个 CompletableFuture 对象。
//返回值:CompletableFuture,没有返回值。
//功能:等待所有给定的 CompletableFuture 对象都完成,返回一个新的 CompletableFuture 对象。
    
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);

CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);

3、异常处理方法

exceptionally(Function<Throwable, ? extends T> fn)
//当 CompletableFuture 执行过程中发生异常时,使用指定的函数进行异常处理,并返回一个新的 CompletableFuture 对象
    
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("任务执行异常");
});

CompletableFuture<Integer> handledFuture = future.exceptionally(ex -> {
    System.out.println("异常处理:" + ex.getMessage());
    return 0; // 默认值
});
handle(BiFunction<? super T, Throwable, ? extends U> fn) 
//当 CompletableFuture 执行完成时,使用指定的函数处理结果或异常,并返回一个新的 CompletableFuture 对象。
    
    
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42);

CompletableFuture<String> handledFuture = future.handle((result, ex) -> {
    if (ex != null) {
        System.out.println("异常处理:" + ex.getMessage());
        return "默认值";
    } else {
        return "结果:" + result;
    }
});

日夜颠倒头发少 ,单纯好骗恋爱脑 ,会背九九乘法表 ,下雨只会往家跑 ,搭讪只会说你好 ---- 2050781802@qq.com

×

喜欢就点赞,疼爱就打赏

相册 说点什么 简历