Java一学期复习 & 基础入门
学了一学期Java了现在开始复习吧
一、Java开发入门
1.1 Java概述
Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。
由 James Gosling和同事们共同研发,并在 1995 年正式推出。
后来 Sun 公司被 Oracle (甲骨文)公司收购,Java 也随之成为 Oracle 公司的产品。
Java分为三个体系:
JavaSE (J2SE) (Java 2 Platform Standard Edition,java平台标准版)
JavaEE (J2EE) (Java 2 Platform,Enterprise Edition,java平台企业版)
JavaME (J2ME) (Java 2 Platform Micro Edition,java平台微型版)
1.2 JDK, JRE, JVM
JDK(Java Development Kit)又称J2SDK(Java2 Software Development Kit)
是Java开发工具包,它提供了Java的开发环境(提供了编译器javac等工具,用于将java文件编译为class文件)和运行环境(提 供了JVM和Runtime辅助包,用于解析class文件使其得到运行)。如果你下载并安装了JDK,那么你不仅可以开发Java程序,也同时拥有了运行Java程序的平台。JDK是整个Java的核心,包括了Java运行环境(JRE),一堆Java工具tools.jar和Java标准类库 (rt.jar)。
JRE(Java Runtime Enviroment)是Java的运行环境
面向Java程序的使用者,而不是开发者。如果你仅下载并安装了JRE,那么你的系统只能运行Java程序。JRE是运行Java程序所必须环境的集合,包含JVM标准实现及 Java核心类库。它包括Java虚拟机、Java平台核心类和支持文件。它不包含开发工具(编译器、调试器等)。
JVM(Java Virtual Machine)Java 虚拟机
是整个 Java 实现跨平台的最核心的部分,能够运行以 Java 语言写作的软件程序。
二、Java编程基础
2.1 基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
public class First { static int sCnt = 0; int cnt = 0; final int SIZE = 10; static String name = "Quanwei";
public void printArray(int[] array) { System.out.print(array); }
public void addCnt() { ++sCnt; ++cnt; }
public void showCnt() { System.out.println(cnt); }
public static void showName(boolean isOn) { if (isOn) System.out.println(name); }
public static void convert() { int foot; int inch; Scanner in = new Scanner(System.in); foot = in.nextInt(); inch = in.nextInt(); System.out.println((foot + inch / 12f) * 0.3048); in.close(); }
public static void main(String[] args) { convert(); } }
|
2.2 数据类型
八种基本数据类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public class Type { byte y; short s; int i; long l; double d; float f; boolean b; char c;
void show() { System.out.println("byte: " + y); System.out.println("short: " + s); System.out.println("int: " + i); System.out.println("long: " + l); System.out.println("double: " + d); System.out.println("float: " + f); System.out.println("boolean: " + b); System.out.println("char: " + c); }
void assign() { y = -1; s = 1; i = 2; l = 3L; d = 12.5; f = 6.25F; b = true; c = 'c'; }
public static void main(String[] args) { Type type = new Type(); type.assign(); type.show(); } }
|
2.3 运算符
类型 |
运算符 |
成员访问运算符 |
. |
下标运算符 |
[ ] |
函数调用运算符 |
( ) |
算数运算符 |
* 乘 / 除 % 取余 + - |
按位运算 |
& 与 | 或 ~ 取反 ^ 异或 << 左移 >> 右移 >>> 无符号右移 |
逻辑运算 |
& | !非 && 短路与 || 短路非 |
条件运算 |
< > <= >= == != |
条件运算符 |
? : |
赋值运算符 |
= += -= *= /= <<= >>= >>>= &= |= ^= |
2.4 选择结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| boolean condition=true; if (condition) { }else{
} if (condition){ }else if(!condition){
}else{
} switch (key) { case value: break; default: break; }
|
2.5 循环结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| boolean condition = true; while (condition) { break; }
do { continue; } while (condition);
for (int i = 0; i < 100; i++) { }
|
三、面向对象
面向对象的优点:
可重用性:代码重复使用,减少代码量,提高开发效率。
可扩展性:指新的功能可以很容易地加入到系统中来,便于软件的修改。
可管理性:能够将功能与数据结合,方便管理。
3.1 概念
Java 是面向对象的编程语言,对象就是面向对象程序设计的核心。
所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。对象有以下特点:
1. 对象具有属性和行为。
2. 对象具有变化的状态。
3. 对象具有唯一性。
4. 对象都是某个类别的实例。
5. 一切皆为对象,真实世界中的所有事物都可以视为对象。
3.2 特性(封装, 继承, 多态)
3.2.1 封装
为什么要封装?
1. 保护类中的信息,它可以阻止在外部定义的代码随意访问内部代码和数据。
2. 隐藏细节信息,一些不需要程序员修改和使用的信息,用户不需要知道。
3. 有助于建立各个系统之间的松耦合关系,提高系统的独立性。当一个系统的实现方式发生变化时,只要它的接口不变,就不会影响其他系统的使用。
4. 提高软件的复用率,降低成本。每个系统都是一个相对独立的整体,可以在不同的环境中得到使用
怎样封装? (将类中属性设为私有, 公开获取属性值的接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| public class User { private int id; private String username; private String passpord;
public User() { }
public String getPasspord() { return passpord; }
public void setPasspord(String passpord) { this.passpord = passpord; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; } @Override public String toString() { return "id: "+getId()+"\tusername: "+getUsername()+"\tpassword: "+getPasspord(); } }
|
访问修饰符:
default (即默认,什么也不写):
在同一包内可见,不使用任何修饰符。
使用对象:类、接口、变量、方法。
public :
对所有类可见。
使用对象:类、接口、变量、方法 protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。
private :
在同一类内可见。
使用对象:变量、方法。 注意:不能修饰类(外部类)
protected :
对同一包内的类和所有子类可见。
使用对象:变量、方法。 注意:不能修饰类(外部类)
注意:
父类中声明为 public 的方法在子类中也必须为 public。 父类中声明为 protected的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private 父类中声明为 private的方法,不能够被继承
3.2.2 继承
什么是继承?
程序中的继承性是指子类拥有父类的全部特征和行为,这是类之间的一种关系。Java 只支持单继承。
如何继承? (使用关键字 extends)
1 2 3 4 5 6 7
| public class VipUser extends User { public static void main(String[] args) { VipUser vip = new VipUser(); vip.setUsername("Quanwei"); System.out.println(vip.getUsername()); } }
|
3.2.3 多态
什么是多态?
面向对象的多态性,即“一个接口,多个方法”。
为什么要使用多态?
多态性体现在父类中定义的属性和方法被子类继承后,可以具有不同的属性或表现方式。
多态性允许一个接口被多个同类使用,弥补了单继承的不足。
如何使用多态? ( 重写父类方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package lang.aboutclass;
public class VipUser extends User { private int vipNum;
@Override public String toString() { return super.toString() + "\tvipNum: " + getVipNum(); }
public int getVipNum() { return vipNum; }
public void setVipNum(int vipNum) { this.vipNum = vipNum; }
public static void main(String[] args) { User user = new VipUser(); user.setUsername("Quanwei"); if (user instanceof VipUser vip) { vip.setVipNum(5432); System.out.println(vip.getUsername()); System.out.println(vip); } } }
|
非访问修饰符
static 修饰符
静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
静态方法:
static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
final 修饰符
final 变量:
final 表示”最后的、最终的”含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。
final 修饰符通常和 static 修饰符一起使用来创建类常量。
final 方法:
父类中的 final 方法可以被子类继承,但是不能被子类重写。
final 类:
final 类不能被继承,没有类能够继承 final 类的任何特性。
abstract 修饰符
抽象类:
抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
抽象类可以包含抽象方法和非抽象方法。
抽象方法
抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。
抽象方法不能被声明成 final 和 static。
任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。
抽象方法的声明以分号结尾,例如:public abstract sample();。
3.3 特殊类
3.3.1 抽象类 ( Abstract Class)
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类不能用于实例化对象
如何定义? (使用abstract关键字)
1 2 3 4 5 6 7 8 9
| public abstract class Human { String name; int age; String language;
public abstract void say(); }
|
如何使用? (继承)
1 2 3 4 5 6 7 8 9 10 11
| class Chinese extends Human { Chinese(String name, String language) { this.name = name; this.language = language; }
@Override public void say() { System.out.println(name + " says " + language); } }
|
3.3.2 接口 (Interface)
是一个抽象类型,是抽象方法的集合。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法。
如何定义? (使用interface关键字)
1 2 3 4 5 6 7
|
public interface Runnable { void run(); }
|
如何使用? (使用implements关键字实现接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Chinese extends Human implements Runnable{ Chinese(String name, String language) { this.name = name; this.language = language; }
@Override public void say() { System.out.println(name + " says " + language);
}
@Override public void run() { System.out.println("I am Running..."); } }
|
3.3.3 内部类 ( Inner Class )
Java 一个类中可以嵌套另外一个类, 即内部类
如何定义?
1 2 3 4 5 6 7 8 9 10 11 12
| class OuterClass { String infomation = "Outer class";
class InnerClass { String information = "Inner class";
class InsiderClass { String information = "Insider class";
} } }
|
如何使用? ( 外部类.new 内部类名() )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package lang.aboutclass;
import lang.aboutclass.OuterClass.InnerClass; import lang.aboutclass.OuterClass.InnerClass.InsiderClass;
class Main { public static void main(String[] args) { OuterClass outer = new OuterClass(); InnerClass inner = outer.new InnerClass(); InsiderClass insider = inner.new InsiderClass(); System.out.println(outer.infomation); System.out.println(inner.information); System.out.println(insider.information); } }
|
3.3.4 枚举类 ( Enum )
Java 枚举是一个特殊的类,一般表示一组常量
如何定义? (使用 enum 关键字来定义,各个常量使用逗号 , 来分割)
1 2 3
| public enum Weekday { SUN, MON, TUE, WED, THU, FRI, SAT; }
|
如何使用? (枚举类名.常量)
1
| System.out.println(Weekday.FRI);
|
3.3.6 记录类
1 2 3
| public record Point(int x, int y) { }
|
相当于:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public final class Point extends Record {
private final int x;
private final int y;
public Point(int x, int y) { this.x = x; this.y = y; }
public int x() { return this.x; }
public int y() { return this.y; }
public String toString() { return String.format("Point[x=%s, y=%s]", x, y); }
public boolean equals(Object o) {
|
也可以在里面写构造函数
1 2 3 4 5 6 7 8
| public record Point(int x, int y) { public Point { if (x < 0 || y < 0) { throw new IllegalArgumentException(); } } }
|
3.3.6 注解类(Annotation)
Java 语言中的类、方法、变量、参数和包等都可以被标注。
和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。
如何定义? ( 使用@interface关键字 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package lang.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target(ElementType.LOCAL_VARIABLE) @Retention(RetentionPolicy.RUNTIME) public @interface Report { int type() default 0;
String level() default "info";
String value() default ""; }
|
元注解(meta annotation) 有一些注解可以修饰其他注解,这些注解就称为元注解
最常用的元注解是@Target。
使用@Target可以定义Annotation能够被应用于源码的哪些位置:
类或接口:ElementType.TYPE;
字段:ElementType.FIELD;
方法:ElementType.METHOD;
构造方法:ElementType.CONSTRUCTOR;
方法参数:ElementType.PARAMETER
另一个重要的元注解@Retention定义了Annotation的生命周期:
仅编译期:RetentionPolicy.SOURCE;
仅class文件:RetentionPolicy.CLASS; (默认)
运行期:RetentionPolicy.RUNTIME
如何使用? ( 通过反射获取注解信息 )
1 2 3 4 5 6 7 8 9
| @MyAnnotation(value = 20, name = "Quanwei") public class MyAnnoTest {
public static void main(String[] args) { MyAnnotation anno = MyAnnoTest.class.getDeclaredAnnotation(MyAnnotation.class); System.out.println(anno.name()); System.out.println(anno.value()); } }
|
在注解的定义中使用注解:
1 2 3 4 5 6 7 8 9
| @Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { int value() default 12;
String name() default "quanwei";
Report report()default @Report ; }
|
3.4 反射 Reflection
是什么?
反射就是一种能在程序 运行 时获取类、接口、方法和变量等信息的能力。
有什么用?
解决在运行期,对某个实例一无所知的情况下,调用其方法
如何使用? (类名.class)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class Main { public static void main(String[] args) throws Exception { Class<Student> stdClass = Student.class; System.out.println(stdClass.getMethod("getScore", String.class)); System.out.println(stdClass.getMethod("getName")); System.out.println(stdClass.getDeclaredMethod("getGrade", int.class)); } }
class Student extends Person { public int getScore(String type) { return 99; } @SuppressWarnings("unused") private int getGrade(int year) { return 1; } }
class Person { public String getName() { return "Person"; } }
|
还有多种情况,参考
3.5 lambda表达式
lambda表达式也即匿名函数, 允许把函数作为一个方法的参数(函数作为参数传递进方法中)
在java中lambda表达式本质上是一个对象
基本的语法像这样:
(parameters) ->{ statements; }
基本使用
1 2 3 4 5 6 7
| new Thread(() -> { try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } }).start();
|
3.6 异常
异常主要指程序运行的时候,会发生各种错误, 不包括编译时发生的
异常可以捕获:
1 2 3 4 5 6 7
| try{ int i=10/0; }catch(Exception e){ e.printStackTrace(); }finally{ }
|
也可以抛出
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void test() throws IOException { testException(10,0); }
public static void testException(int a, int b) throws RuntimeException { if (b > 0) { System.out.println(a / b); } else { throw new RuntimeException("除数不能为零"); } }
|
还可以自定义异常 (继承Exception类)
1 2 3 4 5
| public class MyException extends Exception { public MyException(String msg) { super(msg+" from MyException"); } }
|
四、常用类
4.1 数组 & Arrays
数组的定义和使用
1 2 3 4 5 6 7 8 9 10 11 12 13
| int[] array=new int[10];
for (int i = 0; i < array.length; i++) { array[i]=i+1; }
for (int i : array) { System.out.print(i+" "); }
int[] a2={1,2,2,3,4}; String[] strings={"asd","sdas"};
|
Arrays 类是一个工具类,其中包含了数组操作的很多方法。 Arrays 类里均为 static 修饰的方法可以直接通过类名调用。
例如使用Arrays对数组排序
1 2 3 4 5 6 7 8
| String[] strings = { "hello", "thank", "you", "are", "ok" };
Arrays.sort(strings); System.out.println(Arrays.toString(strings));
Arrays.sort(strings, Comparator.reverseOrder()); System.out.println(Arrays.toString(strings));
|
4.2 String, StringBuffer和StringBuilder
4.2.1 String
String 是 final 修饰的,无法被继承。且 String 不是 Java 的基本数据类型
通过new创建的String对象,和直接赋值的String对象稍有不同:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
public class TestString {
public static void main(String[] args) {
} public void testStringJoint() { String s1 = "Quanwei"; String s2 = "Quanwei"; String s3 = new String("Quanwei"); System.out.println("s1 == s2: " + (s1 == s2)); System.out.println("s1 == s3: " + (s1 == s3)); System.out.println("s1.equals(s2): " + (s1.equals(s2))); System.out.println("s1.equals(s3): " + (s1.equals(s3)));
String s4 = "TangQuanwei"; String s5 = "Tang" + "Quanwei"; System.out.println("s4 == s5: " + (s4 == s5)); String s6 = "Tang" + s1; System.out.println("s4 == s6: " + (s4 == s6)); }
public void testToCharArray() { String s1 = "Quanwei"; char[] charArray = s1.toCharArray(); System.out.println(Arrays.toString(charArray));
String s2 = "权威"; char[] charArray2 = s2.toCharArray(); System.out.println(Arrays.toString(charArray2));
}
public void testGetBytes() { String s1 = "Quanwei"; byte[] bytes = s1.getBytes(); System.out.println(Arrays.toString(bytes));
String s2 = "权威"; byte[] bytes2 = s2.getBytes(); System.out.println(Arrays.toString(bytes2));
try { byte[] bytes3 = s2.getBytes("gbk"); System.out.println(Arrays.toString(bytes3));
byte[] bytes4 = s2.getBytes("utf-8"); System.out.println(Arrays.toString(bytes4)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }
|
String 是不可变的,而 StringBuffer 和 StringBuilder 是可变类
4.2.2 StringBuffer和StringBuilder
二者区别就是:
StringBuffer |
StringBuilder |
线程安全 |
非线程安全 |
同步 |
非同步 |
慢 |
快 |
所以在非多线程环境中的字符串操作,我们一般用 StringBuilder , 因为二者的方法都是差不多的 |
|
它们为字符串操作提供了 append、insert、delete 和 substring 方法 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public void testStringBuilder() { var sb1 = new StringBuilder("Tang"); var sb2 = new StringBuilder("t"); System.out.println(sb1.capacity()); System.out.println(sb1.length()); sb1.ensureCapacity(40); System.out.println(sb1.capacity()); System.out.println(sb2.capacity()); sb1.append("Quawnei"); System.out.println(sb1); sb1.insert(4, "->"); System.out.println(sb1); sb1.delete(0, 4); System.out.println(sb1); }
|
4.3 System类和Runtime类
4.3.1 静态字段
System 类有 3 个静态成员变量,分别是 PrintStream out、InputStream in 和 PrintStream err
out跟err的区别大概是:
System.out.println可能会被缓冲,而System.err.println不会,由于err不需要缓冲即可输出
PrintStream out
1
| System.out.println("quanwei);
|
InputStream in
1 2 3 4 5
| try { int read = System.in.read(); } catch (IOException e) { e.printStackTrace(); }
|
4.3.2 静态方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public static void main(String[] args) { String jversion = System.getProperty("java.version"); String oName = System.getProperty("os.name"); String user = System.getProperty("user.name"); System.out.println("Java 运行时环境版本:" + jversion); System.out.println("当前操作系统是:" + oName); System.out.println("当前用户是:" + user);
Date date = new Date(System.currentTimeMillis()); System.out.println(date);
int[] a = { 1, 2, 3, 4, 5 }; int[] b = { 2, 3, 4, 5, 6 }; int[] marge = marge(a, b); System.out.println(Arrays.toString(marge));
System.gc();
System.exit(0); }
public static int[] marge(int[] a, int[] b) { int[] ret = new int[a.length + b.length]; System.arraycopy(a, 0, ret, 0, a.length); System.arraycopy(b, 0, ret, a.length, b.length); return ret; }
|
4.4 包装类
| 基本类 | 包装类 |
|-|-|-|
|byte| Byte|
|short | Short|
|int | Integer|
|long | Long|
|char | Character|
|float| Float|
|double | Double|
|boolean | Boolean|
常用方法 :
包装类名.parseXxx(String );
包装类名.valueOf(String );
包装类名.toString();
4.5 Math和Random
Math类就是用来进行数学计算的,它提供了大量的静态方法来便于我们实现数学计算
比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| double pi = Math.PI; double e = Math.E;
Math.abs(-100); Math.abs(-7.8);
Math.max(100, 99); Math.min(1.2, 2.3);
Math.pow(2, 10);
Math.sqrt(2);
Math.exp(2);
Math.log(4);
Math.log10(100);
Math.sin(3.14); Math.cos(3.14); Math.tan(3.14); Math.asin(1.0); Math.acos(1.0);
|
4.6 BigInteger类和BigDecimal类
在Java中,由CPU原生提供的整型最大范围是64位long型整数。使用long型整数可以直接通过CPU指令进行计算, 如果我们使用的整数范围超过了long型就只能用软件来模拟一个大整数。java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数
由于Java不支持运算符重载, 在对BigInteger做运算的时候,只能使用对象的方法,例如,
1 2 3
| BigInteger i1 = new BigInteger("1234567890"); BigInteger i2 = new BigInteger("12345678901234567890"); BigInteger sum = i1.add(i2);
|
BigDecimal和BigInteger类似,可以用来表示一个任意大小且精度完全准确的浮点数
1 2 3 4 5 6 7 8
| BigDecimal d1 = new BigDecimal("9876543210.0123456789"); BigDecimal d2 = new BigDecimal("123.45000000000000000"); System.out.println(d1.scale()); System.out.println(d1.add(d2)); System.out.println(d1.subtract(d2)); System.out.println(d1.multiply(d2));
System.out.println(d1.divide(d2, 10, RoundingMode.HALF_UP));
|
4.7 时间和日期类
JDK8以前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;
public class TestBefer8 { public void testTime() { System.out.println("TestDateTime.testTime()"); long currentTimeMillis = System.currentTimeMillis(); System.out.println(currentTimeMillis); } public void testDate() { Date d1 = new Date(); System.out.println(d1); System.out.println(d1.getTime());
var d2 = new Date(1631504736660L); System.out.println(d2);
var d3 = new java.sql.Date(0L); System.out.println(d3);
Date d4 = (Date) d3; System.out.println(d4);
java.sql.Date d5 = new java.sql.Date(d4.getTime()); System.out.println(d5); }
public void testFormat() { System.out.println("TestDateTime.testFormat()");
SimpleDateFormat sdf = new SimpleDateFormat(); Date date = new Date(); String format = sdf.format(date); System.out.println(format);
final String parttern = "yyyy-MM-dd hh:mm:ss:SSS z"; SimpleDateFormat sdf2 = new SimpleDateFormat(parttern); System.out.println(sdf2.format(date));
try { String str = "2021/9/13 下午2:58"; String s2 = "2002-10-09 08:31:12:234 CST"; Date d1 = sdf.parse(str); System.out.println(d1); } catch (ParseException e) { e.printStackTrace(); } }
public void testCalender() { Calendar cal = Calendar.getInstance(); Calendar instance2 = Calendar.getInstance(); System.out.println(cal.getClass()); System.out.println(cal.equals(instance2)); System.out.println(cal.get(Calendar.DAY_OF_MONTH)); System.out.println(cal.get(Calendar.DAY_OF_YEAR)); } }
|
JDK8以后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; import java.time.temporal.TemporalAccessor;
public class TestIn8 { public void testDate() { LocalDate now = LocalDate.now(); System.out.println(now); }
public void testTime() { LocalTime now = LocalTime.now(); System.out.println(now); }
public void testLocalDateTime() { LocalDateTime now = LocalDateTime.now(); System.out.println(now);
LocalDateTime of = LocalDateTime.of(2002, 10, 9, 16, 34, 35); System.out.println(of);
System.out.println(now.getDayOfMonth()); System.out.println(now.getDayOfYear()); System.out.println(now.getChronology()); }
public void testInstant() { Instant now = Instant.now(); System.out.println(now);
OffsetDateTime offSet = now.atOffset(ZoneOffset.ofHours(8)); System.out.println(offSet);
long epochMilli = now.toEpochMilli(); System.out.println(epochMilli);
Instant ofEpochMilli = Instant.ofEpochMilli(1631521135573L); System.out.println(ofEpochMilli); }
public void testDateTimeFormater() { LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; String format = formatter.format(now); System.out.println(format);
TemporalAccessor parse = formatter.parse("2021-09-13T16:56:14.4738222"); System.out.println(parse);
DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); String format2 = formatter2.format(now); System.out.println(format2);
final String pattern="GG yyyy年MM月dd日 EE a hh时mm分ss秒"; DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern(pattern); String format3 = formatter3.format(LocalDateTime.now()); System.out.println(format3); } }
|
五、集合
Java Collection Framework (JCF) Java集合框架是一组提供现成架构的类和接口。为了实现一个新特性或一个类,不需要定义一个框架。然而,一个最佳的面向对象设计总是包含一个具有类集合的框架,这样所有的类都执行相同类型的任务。
5.1 Collection和Collections
Collections
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| public static void main(String[] args) { List<String> ls = new ArrayList<>(); ls.add("reverse"); ls.add("shuffle"); ls.add("sort"); ls.add("swap"); ls.add("rotate"); System.out.println(ls);
Collections.reverse(ls); System.out.println(ls);
Collections.sort(ls); System.out.println(ls);
Collections.sort(ls, new Comparator<String>() {
@Override public int compare(String o1, String o2) { return -o1.compareTo(o2); }
}); System.out.println(ls);
Collections.swap(ls, 0, ls.size() - 1); System.out.println(ls);
Collections.rotate(ls, 2); System.out.println(ls);
Collections.rotate(ls, -3); System.out.println(ls);
ls.add("sort"); int frequency = Collections.frequency(ls, "sort"); System.out.println(frequency);
List<String> l2 = new LinkedList<>(); l2.add("reverse1"); l2.add("shuffle1"); l2.add("sort1"); l2.add("swap1"); l2.add("rotate1"); Collections.copy(ls, l2); System.out.println(ls);
Collections.copy(l2, ls); System.out.println(ls); }
|
5.2 常用类, 接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
public void testList() { List<Integer> al = new ArrayList<>(); List<Integer> ll = new LinkedList<>(); }
public void testQueue() { Queue<Integer> ad = new ArrayDeque<>(); Queue<Integer> ll = new LinkedList<>(); Queue<Integer> pq = new PriorityQueue<>();
}
public void testSet() { Set<Object> hs = new HashSet<>(); Set<Object> ts = new TreeSet<>();
}
public void testMap() { Map<Integer, String> hm = new HashMap<>(); Map<Integer, String> tm = new TreeMap<>(); }
|
5.5 Stream API
在 Java 8 中引入的 Stream API 用于处理对象的集合。流是支持各种方法的对象序列,这些方法可以流水线化以产生所需的结果。
Java 流的特点是:
流不是数据结构,而是从集合、数组或 I/O 通道获取输入。
流不会更改原始数据结构,它们仅根据流水线方法提供结果。
每个中间操作都被延迟执行并返回一个流作为结果,因此可以对各种中间操作进行流水线化。终端操作标记流的结束并返回结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public void testStream() { List<Integer> number = Arrays.asList(2, 3, 4, 5);
List<Integer> square = number.stream().map(x -> x * x).collect(Collectors.toList()); System.out.println(square);
List<String> names = Arrays.asList("Reflection", "Collection", "Stream");
List<String> result = names.stream().filter(s -> s.startsWith("S")).collect(Collectors.toList()); System.out.println(result);
List<String> show = names.stream().sorted().collect(Collectors.toList()); System.out.println(show);
List<Integer> numbers = Arrays.asList(2, 3, 4, 5, 2);
Set<Integer> squareSet = numbers.stream().map(x -> x * x).collect(Collectors.toSet()); System.out.println(squareSet);
number.stream().map(x -> x * x).forEach(y -> System.out.print(y + " "));
int even = number.stream().filter(x -> x % 2 == 0).reduce(0, (ans, i) -> ans + i);
System.out.println(even); }
|
5.6 泛型
泛型意味着参数化类型。这个想法是允许类型(整数、字符串等,以及用户定义的类型)作为方法、类和接口的参数。使用泛型,可以创建使用不同数据类型的类。
对参数化类型进行操作的实体(例如类、接口或方法)称为泛型实体。
与 C++ 一样,我们使用 <> 来指定泛型类创建中的参数类型。要创建泛型类的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| class Pair<T, U> { private T first; private U second;
public Pair(T first, U second) { this.setFirst(first); this.setSecond(second); }
public U getSecond() { return second; }
public void setSecond(U second) { this.second = second; }
public T getFirst() { return first; }
public void setFirst(T first) { this.first = first; }
@Override public String toString() { return "( " + first + ", " + second + ")"; } }
|
六、I/O流
IO是指Input/Output,即以内存为中心的输入和输出。
6.1 BIO
BIO即 Blocking Input/Output, 即阻塞的I/O
6.1.1 Flie
用于文件和目录的创建、文件的查找和文件的删除等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| package lang.io;
import java.io.File; import java.io.IOException;
import org.junit.jupiter.api.Test;
public class TestFile { File floder = new File("D:\\workspaceFolder\\CODE_JAVA"); File file = new File("D:\\workspaceFolder\\CODE_JAVA\\a.txt");
@Test public void testGet() { System.out.println(file); System.out.println(file.getPath()); System.out.println(file.getAbsolutePath()); try { System.out.println(file.getCanonicalPath()); } catch (IOException e) { e.printStackTrace(); }
for (var i : floder.listFiles()) { System.out.println(i); } }
@Test public void testCreate() { File f = new File("test.file"); if (!f.exists()) { try { f.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } }
@Test public void testDelete() { File f = new File("test.file"); if (f.exists()) { boolean delete = f.delete(); System.out.println(delete?"delete":"not exist"); } }
}
|
6.1.2 ByteStream
即字节流, InputStream和OutputStream都是抽象类在里面分别定义了read()和write()方法
我们使用它们的子类, FileInputStream和FileOutputStream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| package lang.io;
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;
import org.junit.Test;
public class TestByteStream {
public void copyPng() { File file = new File("D:\\workspaceFolder\\CODE_JAVA\\猫咪.png"); File fileB = new File("D:\\workspaceFolder\\CODE_JAVA\\猫咪2.png"); FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { fileInputStream = new FileInputStream(file); fileOutputStream = new FileOutputStream(fileB);
int len; byte[] bbuf = new byte[10]; while ((len = fileInputStream.read(bbuf)) != -1) { fileOutputStream.write(bbuf, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fileInputStream != null) fileInputStream.close(); if (fileOutputStream != null) fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
@Test public void read() { File file = new File("D:\\workspaceFolder\\CODE_JAVA\\lang\\io\\TestByteStream.java"); FileInputStream fis = null; try { fis = new FileInputStream(file); int data; while ((data = fis.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } }
}
public static void main(String[] args) { new TestByteStream().copyPng(); } }
|
6.1.3 CharStream
CharStream即字符流
Reader是Java的IO库提供的另一个输入流接口。和InputStream的区别是,InputStream是一个字节流,即以byte为单位读取,而Reader是一个字符流,即以char为单位读取
我们使用Reader的子类FileReader来演示向文件写入数据和从文件读出数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| package lang.io;
import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;
import org.junit.Test;
public class TestCharStream { private final File file = new File("data.txt");
public void Read() { FileReader fileReader = null; try { fileReader = new FileReader(file); int read; while ((read = fileReader.read()) != -1) System.out.print((char) read); } catch (IOException e) { e.printStackTrace(); } finally { if (fileReader != null) try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } }
public void Write(String toBeWrite) { FileWriter fileWriter = null; try { fileWriter = new FileWriter(file); fileWriter.write("By_Quanwei\n"); fileWriter.append(toBeWrite); } catch (IOException e) { e.printStackTrace(); } finally { if (fileWriter != null) try { fileWriter.close(); } catch (IOException e) { e.printStackTrace(); }
} }
public void copyFile(String fileA, String fileB) { FileReader fileReader = null; FileWriter fileWriter = null; try { fileReader = new FileReader(fileA); fileWriter = new FileWriter(fileB); int len; char[] cbuf = new char[10]; while ((len = fileReader.read(cbuf)) != -1) { fileWriter.write(cbuf, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fileReader != null) fileReader.close(); if (fileWriter != null) fileWriter.close(); } catch (Exception e) { e.printStackTrace(); } } }
public static void main(String[] args) { new TestCharStream().copyFile("data.txt", "file.txt"); }
@Test public void testFileReadWite() { TestCharStream testIO = new TestCharStream(); testIO.Write(""" public void Read() { try { FileReader fileReader = new FileReader(file); int read; while ((read = fileReader.read()) != -1) System.out.print((char)read); fileReader.close(); } catch (IOException e) { e.printStackTrace(); } }
public void Write(String toBeWrite) { try { FileWriter fileWriter = new FileWriter(file); fileWriter.append(toBeWrite); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } """); testIO.Read(); } }
|
Socket与网络编程
1.网络编程的两个主要问题 1)如何定位网络上的一台或多态主机,定位主机上的特定应用(IPhe端口) 2)找到主机后如何高效可靠的传输数据(TCP/IP)
本地回环地址: (hostAddress):127.0.0.1
主机名: (hostName):localhost
局域网地址: 192.168.~
端口号: 运行的程序(0-65535)
Sockst = ip + 端口号
TCP 可靠, 大量(三次握手, 四次挥手)
UDP 快速
Url类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package lang.net;
import java.net.URL;
public class MyUrl { public static void main(String[] args) { try { URL url = new URL("https://www.bilibili.com/video/BV1Kb411W75N?p=629"); System.out.println(url.getAuthority()); System.out.println(url.getDefaultPort()); System.out.println(url.getFile()); System.out.println(url.getPath()); System.out.println(url.getProtocol()); } catch (Exception e) { e.printStackTrace(); } } }
|
InetAddress类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| try { InetAddress Aliyun = InetAddress.getByName("39.99.54.127"); InetAddress localHost = InetAddress.getLocalHost(); InetAddress loopbackAddress = InetAddress.getLoopbackAddress(); boolean reachable = localHost.isReachable(10); System.out.println(reachable); System.out.println(localHost); System.out.println(Aliyun); String canonicalHostName = Aliyun.getCanonicalHostName(); String hostName = Aliyun.getHostName(); System.out.println(hostName); System.out.println(canonicalHostName); System.out.println(loopbackAddress); } catch (Exception e) { e.printStackTrace(); }
|
UDP网络编程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
@Test public void UDPReciver() { DatagramSocket server = null; try { server = new DatagramSocket(8900); byte[] buf = new byte[1024]; DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length); System.out.println("waiting..."); while (true) { server.receive(datagramPacket); String string = new String(datagramPacket.getData(), 0, datagramPacket.getLength()); System.out.println(datagramPacket.getAddress() + ":" + datagramPacket.getPort() + "send: " + string); } } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (server != null) server.close(); }
}
@Test public void UDPSender() { DatagramSocket client = null; try { client = new DatagramSocket(); String str = "hello Quanwei"; DatagramPacket datagramPacket = new DatagramPacket(str.getBytes(), str.getBytes().length, InetAddress.getLocalHost(), 8900); System.out.println("start send..."); client.send(datagramPacket); } catch (SocketException | UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (client != null) client.close(); } }
|
TCP网络编程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
| package lang.net;
import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.time.LocalDateTime;
public class TCP {
public void clientResive() { Socket socket = null; InputStream inputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; try { InetAddress ip = InetAddress.getByName("127.0.0.1"); socket = new Socket(ip, 8899); inputStream = socket.getInputStream(); byte[] buf = new byte[1024]; int len; byteArrayOutputStream = new ByteArrayOutputStream(); while ((len = inputStream.read(buf)) != -1) { byteArrayOutputStream.write(buf, 0, len); }
System.out.println(LocalDateTime.now() + " get from server: " + byteArrayOutputStream);
} catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (byteArrayOutputStream != null) try { byteArrayOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } if (inputStream != null) try { inputStream.close(); } catch (IOException e1) { e1.printStackTrace(); } if (socket != null) try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
public void clientSend() { Socket socket = null; InetAddress ip; OutputStream outputStream = null;
try { ip = InetAddress.getByName("127.0.0.1"); socket = new Socket(ip, 8899); outputStream = socket.getOutputStream(); outputStream.write("权威 Quanwei".getBytes()); } catch (Exception e) { e.printStackTrace(); } finally { if (outputStream != null) try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } if (socket != null) try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
public void serverRevive() { ServerSocket server = null; Socket accept = null; InputStream inputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; FileOutputStream fileOutputStream = null; try { server = new ServerSocket(8899); accept = server.accept(); inputStream = accept.getInputStream(); byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len; while ((len = inputStream.read(buf)) != -1) { byteArrayOutputStream.write(buf, 0, len); } System.out.println(LocalDateTime.now() + " get from client: " + byteArrayOutputStream);
fileOutputStream = new FileOutputStream(new File("D:\\workspaceFolder\\CODE_JAVA\\lang\\net\\file")); fileOutputStream.write(byteArrayOutputStream.toByteArray());
} catch (IOException e) { e.printStackTrace(); } finally { if (byteArrayOutputStream != null) try { byteArrayOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } if (inputStream != null) try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } if (accept != null) try { accept.close(); } catch (IOException e) { e.printStackTrace(); } if (server != null) try { server.close(); } catch (IOException e) { e.printStackTrace(); } } }
public void serverSend() { ServerSocket server = null; Socket accept = null; OutputStream outputStream = null; try { server = new ServerSocket(8899); accept = server.accept(); outputStream = accept.getOutputStream(); outputStream.write("接收成功".getBytes()); } catch (Exception e) { e.printStackTrace(); } finally { if (outputStream != null) try { outputStream.close(); } catch (IOException e1) { e1.printStackTrace(); } if (accept != null) try { accept.close(); } catch (IOException e) { e.printStackTrace(); } if (server != null) try { server.close(); } catch (IOException e) { e.printStackTrace(); } } }
public static void main(String[] args) { TCP tcp = new TCP(); new Thread(() -> { tcp.serverSend(); }).start(); new Thread(() -> { tcp.clientResive(); }).start(); } }
|
6.2 NIO
6.3 AIO
七、多线程
多线程是Java最基本的一种并发模型
一个线程不能独立的存在,它必须是进程的一部分。
进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。
创建多线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package lang.thread;
import org.junit.jupiter.api.Test;
public class CreateThreadDemo {
@Test public void testLambda() { new Thread(() -> { String name = Thread.currentThread().getName(); System.out.println(name); }, "Quanwei's thread").start(); }
@Test public void testExtends() { new Thread() { public void run() { String name = Thread.currentThread().getName(); System.out.println("Extends" + name); } }.start(); ; }
@Test public void testImplements() { Runnable runnable = new Runnable() { @Override public void run() { String name = Thread.currentThread().getName(); System.out.println(name); } }; new Thread(runnable,"Implements").start(); }
public static void main(String[] args) { new CreateThreadDemo().testLambda(); System.out.println(Thread.currentThread().getName()); }
}
|
多线程通信
同步代码块
synchronized(同步监视器){//同步监视器可用: 类.class(保证唯一)
//要同步的代码
}
不需要synchronized的操作 JVM规范定义了几种原子操作:
- 基本类型(long和double除外)赋值,例如:int n = m; 引用类型赋值,例如:List list = anotherList。
- long和double是64位数据,JVM没有明确规定64位赋值操作是不是一个原子操作,不过在x64平台的JVM是把long和double的赋值作为原子操作实现的
- 单条原子操作不需要线程同步,多条需要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class Ticket { public static void main(String[] args) { var w = new Windows1(); var w1 = new Thread(w, "w1"); var w2 = new Thread(w, "w2"); var w3 = new Thread(w, "w3"); w2.setPriority(Thread.MAX_PRIORITY); w1.start(); w2.start(); w3.start(); } }
class Windows1 implements Runnable { private int tickets = 50; Object obj = new Object();
@Override public void run() { while (true) { synchronized (Windows1.class) { if (tickets > 0) { try { Thread.sleep(100); } catch (Exception e) { } System.out.println(Thread.currentThread().getName() + " : " + tickets); --tickets; } else break; } } }
}
|
八、JDBC
什么是JDBC?
DBC是Java DataBase Connectivity的缩写,它是Java程序访问数据库的标准接口。
使用Java程序访问数据库时,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而JDBC接口则通过JDBC驱动来实现真正对数据库的访问。
我们在Java代码中如果要访问MySQL,那么必须编写代码操作JDBC接口。注意到JDBC接口是Java标准库自带的,所以可以直接编译。而具体的JDBC驱动是由数据库厂商提供的,。因此,访问某个具体的数据库,我们只需要引入该厂商提供的JDBC驱动,就可以通过JDBC接口来访问,这样保证了Java程序编写的是一套数据库访问代码,却可以访问各种不同的数据库,因为他们都提供了标准的JDBC驱动
如何使用? (以连接PostgreSQL为例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import org.postgresql.Driver;
public class Postgresql { private static String url = "jdbc:postgresql://localhost:5432/quanwei"; private static String user = "postgres"; private static String password = "password"; private static String driver = "org.postgresql.Driver";
public static void main(String[] args) throws SQLException { Driver driver = new org.postgresql.Driver();
Properties prop = new Properties(); prop.setProperty("user", user); prop.setProperty("password", password);
Connection conn = null; try { conn = driver.connect(url, prop); } catch (SQLException e) { e.printStackTrace(); } Statement s = conn.createStatement(); ResultSet rs = s.executeQuery("select * from login"); while(rs.next()){ String string = rs.getString(2); System.out.println(string); } } }
|
九、GUI
9.1 AWT
即抽象窗口工具包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package lang.gui;
import java.awt.*; import java.awt.event.*;
public class HelloAWT { public static void main(String[] args) { Frame frame = new Frame("AWT"); Label label = new Label("Hello Quanwei"); label.setBackground(Color.GREEN); label.setSize(20, 10); frame.add(label); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(500, 200); frame.setVisible(true); } }
|
9.2 Swing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package lang.gui;
import java.awt.*; import java.awt.event.*; import java.util.HashMap;
import javax.swing.*; import javax.swing.event.*;
public class Main {
public void window1() { JFrame frame = new JFrame("Swing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(500, 500); frame.setLocation(500, 200);
frame.addMouseListener(new MouseInputAdapter() { @Override public void mouseClicked(MouseEvent e) { int x = e.getX(); int y = e.getY(); frame.setTitle("点击坐标为(" + x + ", " + y + ")"); } }); frame.setVisible(true); } }
|
总结
比我想象的要多得多😂😂😂🤣🤣🤣