JAVA基础
计算机组成
硬件+软件
硬件:
-
CPU (控制)
-
硬盘 (主要存储设备、容量大)分为:机械硬盘、固态硬盘(贵、开机和加载速度快)
-
内存 (负责硬盘上的数据与CPU之间数据交换)
-
输入设备 (如:键盘、鼠标)
-
输出设备 (如:打印机)
-
通信设备 (如:网卡)
软件:
-
系统软件 - windows
-
应用软件 - JDK
常用的Dos命令
dir 列出当前目录下的文件和文件夹
cd 目录 切换目录
cd .. 回退上一个目录
md 文件/目录 创建指定文件
rd 文件/目录 删除指定文件
cls 清屏
JDK17
下载地址:https://www.oracle.com/java/technologies/downloads/archive
与JDK8安装不同,下载安装包,可直接安装,不用配置环境变量,默认自动给配置了,可在环境变量PATH里查看,可以看到Oracle\Java\javapath,如果想继续其他版本,可控制上移,下移控制想要的版本。
查看java版本
java -version
JAVA
面向对象的特征:封装、继承、多态、(抽象)
Java类以及成员:属性、方法、构造器、代码块、内部类
基础
JAVA的变量
-
基本类型:byte、short、int、long float、double、char、boolean
-
引用类型:class、array、interface、enum、annotation、record(记录)
static 静态的
案例:
public static final String SO_YES = "解决方案";
private static Integer num = 0;
static {
// 可初始化 - 数据
num = 1;
}
类型转换
// int TO String
int i1 = Integer.parseInt("2");
String s1 = String.valueOf(i1);
// intern TO String
Integer i2 = (Integer) Integer.parseInt("3");
String s2 = String.valueOf(i2);
// int TO Integer转换
int i3 = (int) i2;
Integer s3 = (Integer) i3;
// long和String互相转换的方法
long i4 = 3l;
String s4 = String.valueOf(i4);
i4 = Long.parseLong(s4);
// int 转long
long i5= (long) i3;
int l5 = (int) i5;
// long 转 int
Long a6 = 10L;
int b6 = a6.intValue();
// Integer 转long
long i7= (long) i2;
Integer l7 = (int) i7;
// long 转Integer
Long a = 10L;
Integer bb = a.intValue();
Math
Math.ceil(11.2); // 向上取整 12
Math.floor(11.2); // 向下取整 11
Math.round(11.2); // 四舍五入 11
Math.abs(11.3); // 绝对值
Math.max(11,12); // 返回最大的数
Math.min(11,12); // 返回最小的数
Math.random(); // 返回随机数 0 - 1 直接的小数
int i = (int) Math.random() * 100; // 生产 1 - 100 的随机数
Arrays
// Arrays 来源 java.util包
int[] ints = {1,5,28,21,18};
// 1 数组是否相等 ,参数:数组1,数组2 (比数组里的内容)
boolean equals = Arrays.equals(ints, ints); // true
// 2 数组长度
System.out.println("数组长度:" + ints.length);
// 3 正序快速排序(默认:从小到大)
Arrays.sort(ints);
// 4 打印数组,返回字符串
System.out.println("打印出数组里的内容:" + Arrays.toString(ints));
// 5 替换数组里的元素 (把数组里全部的元素替换成3)
Arrays.fill(ints, 3);
// 6 可变参数 ... 底层就是数组
// public void add(int ... a);
枚举
public enum State {
DRAFT(0, "草稿"),
VALID(2, "有效"),
FINISH(3, "终止"),
DELETE(4, "作废");
private Integer index;
private String name;
State(Integer index, String name) {
this.index = index;
this.name = name;
}
public static String getName(Integer index) {
for (AEnum.State c : AEnum.State.values()) {
if (c.getIndex().equals(index)) {
return c.name;
}
}
return null;
}
public static State getEnum(Integer index) {
return Arrays.stream(values()).filter(t -> t.getIndex().equals(index)).findFirst().orElse(DRAFT);
}
public String getName() {
return name;
}
public Integer getIndex() {
return index;
}
}
字符串
String
// String类 操作
String str = "abc";
// 是否为空
boolean empty = str.isEmpty();
// 比较字符串大小 (如果是负数,代表后面的abc大)
int abc = str.compareTo("abc");
// 比较字符串大小 (忽略大小写)
int abc2 = str.compareToIgnoreCase("abc");
// 大写转小写
String s1 = str.toLowerCase();
// 小写转大写
String s2 = str.toUpperCase();
// 字符串是否包含
boolean a = str.contains("a");
// 返回该查找内容的下标,没有返回-1
int a1 = str.indexOf("a");
// 返回该查找内容的下标,没有返回-1 , 参数2:从某个位置下标后开始查找
int a2 = str.indexOf("a", 3);
// 从后面开始往前查找
int a3 = str.lastIndexOf("a");
// 截取某个字符串 ,从该位置下标(包含当前自己),向后取
String substring = str.substring(1);
// 截取某个字符串 ,从该位置下标(包含当前自己),向后取 ,参数2:取几个,取3个
String substring2 = str.substring(1, 3);
// 返回改下标的字符
char c = str.charAt(2);
// 返回字符串
String s = String.valueOf(new char[]{'b', 'w'});
// 检查字符串是不是以这个为开头
boolean ab1 = str.startsWith("abc");
// 检查字符串是不是以这个为开头 参数2:从某个位置下标后开始查找
boolean ab2 = str.startsWith("abc",3);
// 检查字符串是不是以这个为结束
boolean ab3 = str.endsWith("abc");
// 替换 ,把a替换成c
String replace = str.replace("a", "c");
// 替换 ,参数1:可以是【正则表达式】
String replace2 = str.replaceAll("a", "c");
StringBuilder&StringBuffer
// StringBuilder 非线程安全 StringBuffer 线程安全
StringBuilder s = new StringBuilder();
// 追加
s.append("a").append("b").append("c");
// 在下标为3的位置上,增加h
s.insert(2,"h");
// 从1 - 6的位置,替换成hhh
s.replace(1,3,"hhh");
// 查询有没有这个字符 ,lastIndexOf
s.indexOf("true");
// 从1-6的位置,截取
String s1 = s.substring(1,3);
// 从1-3 删除掉
s.delete(1,3);
// 删除下标是3的字符
s.deleteCharAt(3);
// 长度
int length = s.length();
// 反转
StringBuilder reverse = s.reverse();
Conllection
// 数组转list
List<Integer> integers = Arrays.asList(1, 2, 3);
// list转数组
Integer[] objects = (Integer[]) integers.toArray();
// 是否为空
boolean empty = integers.isEmpty();
// 新增
// integers.add(); integers.addAll();
// 是否包含aa
boolean aa = integers.contains("aa");
boolean aa2 = integers.containsAll(new ArrayList<>());
// 清空
integers.clear();
// 删除 - 如果是对象,需要重新equals方法
integers.remove("aa");
// 两个集合 取交集
integers.retainAll(integers);
// 截取集合1-3位置的数据,包含头,不包含尾
List<Integer> integers1 = integers.subList(1, 3);
// 返回该元素在集合中的小标
int i = integers.indexOf(2);
// 返回该元素在集合中的小标 (从后面查)
int i2 = integers.lastIndexOf(2);
// LinkedList 的方法
LinkedList<Integer> integers2 = new LinkedList<>();
integers2.addFirst(1);
integers2.getFirst(); integers2.getLast();
integers2.removeFirst();
// 堆栈:先进后出 队列:先进先出
Collections 工具类
List<Integer> integers1 = Arrays.asList(1, 2, 3);
// list反转
Collections.reverse(integers1);
// list随机顺序
Collections.shuffle(integers1);
// 自然排序 参数2 定义排序,传递Comparator
Collections.sort(integers1);
Collections.sort(integers1, (a, b) -> {
return Integer.compare(a, b);
});
// 位置交换,将1和3的位置交换
Collections.swap(integers1, 1, 3);
// 最大值 ,参数2,传递Comparator 按照这个方式比较
Integer max = Collections.max(integers1);
Integer max1 = Collections.max(integers1, (a, b) -> {
return a.compareTo(b);
});
// 最小值, 同上
Collections.min(integers1);
// 该list中出现"AA"的次数
int aa1 = Collections.frequency(integers1, "AA");
// 将list中的全部的3替换成4。替换所有的旧值
Collections.replaceAll(integers1, 3, 4);
// list 复制
Collections.copy(integers1, new ArrayList<>(integers1.size()));
// 只读的List (不能写)
List<Integer> integers = Collections.unmodifiableList(integers1);
// 线程安全的List
List<Integer> integers2 = Collections.synchronizedList(integers);
CollectionUtils 工具类
// 需要引入该包
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
List<String> list = Arrays.asList("a", "b", "c");
List<String> lists = Arrays.asList("a", "d", "c");
// 两个集合取交集
Collection collection = CollectionUtils.retainAll(list, lists);
// 两个集合取并集
Collection collection1 = CollectionUtils.union(list, lists);
// 两个集合取差集 就是只有lists里面有的元素
Collection collection2= CollectionUtils.subtract(lists, list);
Map
Map<String, String> map = new HashMap<>();
// 添加、修改
map.put("k1","Tom");
map.putAll(new HashMap<>());
// 删除
map.remove("k1");
// 查
map.get("k1");
// 长度
int size = map.size();
// 是否包含当前的key
boolean k1 = map.containsKey("k1");
// 是否包含当前的Value
boolean k2 = map.containsValue("Tom");
// 是否为空
boolean empty = map.isEmpty();
// 遍历出全部的key
Set<String> strings = map.keySet();
// 遍历出全部的Value
Collection<String> values = map.values();
// 遍历出全部的
Set<Map.Entry<String, String>> entries = map.entrySet();
entries.forEach(x -> {
// key + value
System.out.println(x.getKey() + x.getValue());
});
// 需要引入该包
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<实体> kyrei = new <实体>("kyrei", 12);
// 对象转map
Map<String, String> describe = BeanUtils.describe(kyrei);
// map转对象
<实体> user1 = new <实体>();
BeanUtils.populate(user1,describe);
自定义异常类
public class BaseException extends Exception {
private String errorMessage;
public BaseException(Throwable throwable) {
super(throwable);
}
public BaseException(String errorMessage) {
super(errorMessage);
this.errorMessage = errorMessage;
}
public String getErrorMessage() {
return errorMessage;
}
}
File
// 需要引入该包
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
File file = new File("demo1.txt");
// 读取文件
List<String> lines = FileUtils.readLines(file, Charset.defaultCharset());
// 写入文件
FileUtils.writeLines(new File("demo2.txt"), lines);
// 复制文件
FileUtils.copyFile(srcFile, destFile);
多线程
程序:特定的任务
进程:程序一次执行过程,如:微信语音,播放器播放音乐
线程:一个进程至少有一个线程
并行: 多个任务同时执行
并发:多个指令同时抢占同一个资源
创建线程:
// 方式1
new Thread(name) {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程名字");
};
}.start();
// 方式2
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable创建线程方式2...");
}
}).start();
// 方式3
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "线程名字:");
}).start();
// 方式4
FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>) () -> {
System.out.println(Thread.currentThread().getName() + "线程名字:");
// 有返回值
int i = 0;
return i;
});
Thread t1 = new Thread(task, "t1线程");
t1.start();
try {
System.out.println("子线程的返回值" + task.get());
} catch (Exception e) {
e.printStackTrace();
}
时间
JDK8之前的时间
// 计算耗时时间
long start = System.currentTimeMillis();
Thread.sleep(3000);
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
// 当前时间
Date date = new Date();
// 当前时间戳
long time = date.getTime();
// 时间 转 字符串
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = sdf.format(new Date());
// 字符串 转 时间
Date parse = sdf.parse(format);
// Calendar 日历类 ,注:月份 从0开始
Calendar cal = Calendar.getInstance();
Date time1 = cal.getTime();
JDK8之后的时间
// 当前时间
LocalDate n1 = LocalDate.now(); // 年月日
LocalTime n2 = LocalTime.now(); // 时分秒
LocalDateTime n3 = LocalDateTime.now(); // 年月日 时分秒
// 设置时间
LocalDateTime of = LocalDateTime.of(2018, 2, 22, 2, 22, 54);
// 获取 年 月 日
System.out.println(of.getYear());
System.out.println(of.getMonthValue());
System.out.println(of.getDayOfMonth());
// 加上2年
LocalDateTime of2 = of.plusYears(2);
// 减上2年
LocalDateTime of3 = of.minusYears(2);
// 获取 秒数时间戳(10位)
long l = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
// 获取 毫秒数时间戳(13位)
long l1 = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
// 当前时间 Instant相当于之前的 Date
Instant instant = Instant.now();
// 北京的时间,差8小时
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
// 时间戳
long l2 = instant.toEpochMilli();
// 时间比较
Instant i1 = Instant.now();
// 延迟加载
TimeUnit.SECONDS.sleep(1);
Instant i2 = Instant.now();
long la = Duration.between(i1, i2).toMillis();
System.out.println(la);
// 日期比较
LocalDate ld = LocalDate.of(2018,12,11);
// 延迟加载
TimeUnit.SECONDS.sleep(1);
LocalDate ld2 = LocalDate.now();
Period between = Period.between(ld, ld2);
System.out.println(between.getYears());
System.out.println(between.getMonths());
System.out.println(between.getDays());
时间格式化
LocalDateTime l = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
// 时间转字符串
String format = dtf.format(l);
// 字符串转时间
LocalDateTime parse = LocalDateTime.parse(format, dtf);
// LocalDate 转为 Date
LocalDate localDate = LocalDate.now();
Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant);
System.out.println("LocalDate 转为 Date: " + date);
// Date 转为 LocalDateTime
Date date3 = new Date();
LocalDateTime localDateTime3 = LocalDateTime.ofInstant(date3.toInstant(), ZoneId.systemDefault());
System.out.println("Date 转为 LocalDateTime: " + date3);
// Date 转为 LocalDate
Date date4 = new Date();
LocalDateTime localDateTime4 = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
LocalDate localDate4 = localDateTime4.toLocalDate();
System.out.println("Date 转为 LocalDate: " + localDate4);
TemporalAdjuster:时间校验器
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 2020-07-20T19:28:57.822
// 把日期改成10号
LocalDateTime ldt2 = now.withDayOfMonth(10);
System.out.println(ldt2);
// 把日期改成下个周末
LocalDateTime ldt3 = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(ldt3);
// 自定义--获取下一个工作日
LocalDateTime with = now.with((l) -> {
LocalDateTime ldt4 = (LocalDateTime) l;
DayOfWeek dayOfWeek = ldt4.getDayOfWeek();
// 获取今天周几 ,如果是周五 +3天,周六 +2 ,其它 + 1
if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
return ldt4.plusDays(3);
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
return ldt4.plusDays(2);
} else {
return ldt4.plusDays(1);
}
});
System.out.println(with);
排序
TPojo[] arr = new TPojo[5];
arr[0] = new TPojo("a王",1);
arr[1] = new TPojo("a刘",3);
arr[2] = new TPojo("b时",83);
arr[3] = new TPojo("e物",73);
arr[4] = new TPojo("c活",13);
// 排序
Arrays.sort(arr, (a, b) -> {
// 先比age ,再比较name
int compare = Integer.compare(a.getAge(), b.getAge());
if (compare != 0) {
return compare; // (从小到大)
// return - compare; // (从大到小)
}
return a.getName().compareTo(a.getName());
});
反射
// 反射 获取Class实例
// 方式 1.通过运行时的类的属性class
Class<实体> a1 = 实体.class;
// 方式 2.通过运行的对象
实体 p = new 实体();
Class<? extends 实体> s2 = p.getClass();
// 方式 3.通过Class的静态方法forName()
String p2 = "cn.xxx.类"; // 全路径的包名 + 类名
Class<?> aClass = Class.forName(p2);
// 方式 4.通过类加载器
ClassLoader classLoader = this.getClass().getClassLoader();
Class<?> aClass1 = classLoader.loadClass(p2); // 全路径的包名 + 类名
反射 获取属性、方法、构造器、内部类、注解、接口、父类
Class<APOJO> a1 = APOJO.class;
// 通过反射创建对象
APOJO apojo = a1.newInstance();
// 获取 所有public修饰的属性,包括父类的
Field[] fields = a1.getFields();
for (Field f:fields){
// 获取每个属性的结构
// 获取 修饰符
String s = Modifier.toString(f.getModifiers());
// 获取数据类型
Class<?> type = f.getType();
String name = type.getName();
}
// 获取 本类所有声明的属性,不包含父类
Field[] fields2 = a1.getDeclaredFields();
// 获取 所有public修饰的方法,包括父类的
Method[] methods = a1.getMethods();
for (Method f:methods){
// 获取每个方法的结构
// 获取 修饰符
String s = Modifier.toString(f.getModifiers());
// 获取数 返回值 数据类型
Class<?> type = f.getReturnType();
String name = type.getName();
// 获取方法名
String name1 = f.getName();
// 获取参数列表
Class<?>[] parameterTypes = f.getParameterTypes();
// 获取注解
Annotation[] annotation = f.getAnnotations();
// 获取异常
Class<?>[] exceptionTypes2 = f.getExceptionTypes();
}
// 获取 本类所有声明的方法,不包含父类
Method[] methods2 = a1.getDeclaredMethods();
// 获取 所有public修饰的构造器,包括父类的
Constructor<?>[] c1 = a1.getConstructors();
// 获取 本类所有声明的构造器,不包含父类
Constructor<?>[] c2 = a1.getDeclaredConstructors();
// 获取父类
Class<? super APOJO> superclass = a1.getSuperclass(); // 得到父类的Class
// 获取带泛型的父类的类型
Type type = a1.getGenericSuperclass(); // 得到 com.xxx.父类<java.long.String>
// 获取带泛型的父类的类型的类型
ParameterizedType type1 = (ParameterizedType) type;
Type[] ts = type1.getActualTypeArguments(); // 得到多个类型的Class实例
Class c = (Class) ts[0];
String name = c.getName(); // 得到String类型
// 获取接口
Class<?>[] interfaces = a1.getInterfaces();
// 获取内部类/获取私有的内部类
Class<?>[] classes = a1.getClasses();
Class<?>[] classes2 = a1.getDeclaredClasses();
// 获取注解 注解的生命周期需要是RunTime
Annotation[] annotations = a1.getAnnotations();
for (Annotation a:annotations){
// 注解类 xx = (注解类) a;
// xx.value(); // 注解默认值
}
// 获取包
Package aPackage = a1.getPackage();
反射 操作对象
Class<APOJO> a1 = APOJO.class;
APOJO apojo = a1.newInstance();
// 获取该对象的属性名, 参数:属性名
Field name = a1.getField("name");
// 设置属性值
name.set(apojo,18);
// 获取属性值
Object o = name.get(apojo);
// 获取该对象的属性名,可以获取到 private修饰的
Field name1 = a1.getDeclaredField("name");
name1.setAccessible(true); // 忽略权限
name1.set(apojo,18); // 私有的也可以设置
// 方法
Method getNames = a1.getMethod("getName"); // 获取该对象的方法, 参数:方法名
// 执行这个方法 , 如果有返回值是Object
Object invoke = getNames.invoke(apojo);
// 获取该对象的方法, 参数:方法名,后面是可变参数
Method getNames2 = a1.getMethod("setName",String.class,Integer.class,double.class, BigDecimal.class);
getNames2.invoke(apojo,"ss",1,2.1,new BigDecimal(1));
// 构造器
Constructor<APOJO> constructor = a1.getConstructor(String.class, Integer.class);
APOJO aa = constructor.newInstance("aa", 1); // 通过构造器获取对象
try catch
try (InputStreamReader reader2 = new InputStreamReader(System.in)) {
reader2.read();
} catch (Exception e) {
e.printStackTrace();
}