JDK的组成
JDK是Java Development Kit的缩写, 由JVM、核心类库、开发工具包组成。
JRE是Java Runtime Environment的缩写,由JVM和核心类库组成。
开发工具包包含了编译工具、调试工具、性能分析工具等。例如:javac、java、javadoc、jdb等。
Hello World
package org.example;
public class Main {
public static void main(String[] args) {
System.out.printf("Hello and welcome!");
for (int i = 1; i <= 5; i++) {
System.out.println("i = " + i);
}
}
}
方法重载
方法重载是指在一个类中,多个方法具有相同的名字,但参数列表不同的情况。
- 参数列表不同:参数的个数不同,参数的类型不同,参数的顺序不同。
- 返回值类型不同:方法的返回值类型不同,不能通过返回值类型来区分方法。
- 仅仅通过参数名的不同是不能构成方法的重载的。
package org.example;
public class Main {
public static void main(String[] args) {
// say hello
System.out.println(sayHello());
// say hello to someone
System.out.println(sayHello("Alice"));
// say hello to someone with a title
System.out.println(sayHello("Dr", "Bob"));
}
// say hello
public static String sayHello() {
return "Hello";
}
// say hello to someone
public static String sayHello(String name) {
return "Hello " + name;
}
// say hello to someone with a title
public static String sayHello(String title, String name) {
return "Hello " + title + " " + name;
}
}
数组
数组的定义
数组是相同类型数据的有序集合,数组中的每个数据称为元素,每个元素可以通过一个索引来访问。
public class Main {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
var arr2 = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
var arr3 = new int[10]; // 10 is the size of the array
for (int i = 0; i < arr3.length; i++) {
System.out.println(arr3[i]);
}
}
}
数组反转
public class Main {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
for (int i = 0, j = arr.length-1; i < j; i++, j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
类的创建
package org.example;
class Person {
private String name;
private int age;
// constructor with parameters
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// constructor without parameters
public Person() {
this.name = "Unknown";
this.age = 0;
}
public String getName() {
return name;
}
// set name
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
// set age
public void setAge(int age) {
this.age = age;
}
public void print() {
System.out.println("Name: " + name + ", Age: " + age);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("John", 30);
p1.print(); // Name: John, Age: 30
Person p2 = new Person();
p2.print(); // Name: Unknown, Age: 0
p2.setName("Doe");
p2.setAge(25);
p2.print(); // Name: Doe, Age: 25
}
}
实体JavaBean
实体JavaBean是一个公共类,它具有私有属性,并通过公共方法来设置和获取这些属性。还必须有一个无参构造函数。
package org.example;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
应用场景:
实体JavaBean通常用于数据传输对象(DTO),数据访问对象(DAO)等。也就是只负责数据的存储和读取,不包含业务逻辑。业务逻辑交给其他类处理,以保证数据和业务逻辑的分离。
String
创建字符串
public class Main {
public static void main(String[] args) {
String str1 = new String();
String str2 = "Hello";
char[] char1 = {'你', '好', '啊'};
String str3 = new String(char1);
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
}
}
遍历字符串
String str1 = "Hello";
for (int i = 0; i <str1.length() ; i++) {
System.out.println(str1.charAt(i));
}
char[] charArray = str1.toCharArray();
for (char c : charArray) {
System.out.println(c);
}
字符串比较
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); // true
String str3 = new String("Hello");
String str4 = new String("Hello");
System.out.println(str3 == str4); // false
System.out.println(str3.equals(str4)); // true
String str1 = "Hello";
String str2 = "hello";
System.out.println(str1.equals(str2)); // false
System.out.println(str1.equalsIgnoreCase(str2)); // true
String str1 = "abc";
String str2 = "a" + "b" + "c"; // 编译时优化 "a" + "b" + "c" 会被优化为 "abc"
System.out.println(str1 == str2); // true
字符串截取
String str1 = "Hello";
System.out.println(str1.substring(0, 1)); // H
字符串替换
String str1 = "Hello";
System.out.println(str1.replace("H", "W")); // Output: Wello
字符是否包含
String str1 = "Hello";
System.out.println(str1.contains("H")); // true
字符串拼接
String str1 = "Hello";
str1 += " World";
System.out.println(str1); // Hello World
Static关键字
静态变量
静态变量是属于类的,而不是属于对象的。静态变量在类加载时初始化,不需要创建对象。可以被类的所有对象共享。
public class Main {
public static void main(String[] args) {
User user1 = new User("John");
User user2 = new User("Jane");
User user3 = new User("Doe");
System.out.println(User.count); // 3
}
}
class User {
static int count = 0;
private String name;
public User(String name) {
this.name = name;
count++;
}
public User() {
count++;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
静态方法
静态方法是属于类的,而不是属于对象的。静态方法在类加载时初始化,不需要创建对象。可以直接通过类名调用。
public class Main {
public static void main(String[] args) {
System.out.println(User.getCount()); // 0
User user1 = new User("John");
User user2 = new User("Jane");
User user3 = new User("Doe");
System.out.println(User.getCount()); // 3
}
}
class User {
private static int count = 0;
private String name;
public User(String name) {
this.name = name;
count++;
}
public User() {
count++;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static int getCount() {
return count;
}
}
代码块
代码块是类的五大成员之一 (成员变量、方法、构造器、代码块、内部类)。
静态代码块
- 格式:static {}
- 特点:随着类的加载而执行,只执行一次。
- 作用:用来给类的静态变量赋值。
public class Main {
public static void main(String[] args) {
System.out.println(User.getCount()); // 0
User user1 = new User("John");
User user2 = new User("Jane");
User user3 = new User("Doe");
System.out.println(User.getCount()); // 3
}
}
class User {
private static int count;
private String name;
static {
count = 0;
}
public User(String name) {
this.name = name;
count++;
}
public User() {
count++;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static int getCount() {
return count;
}
}
非静态代码块 (实例代码块)
- 格式:{}
- 特点:每创建一个对象就执行一次,优先于构造器执行。
- 作用:用来给对象的成员变量赋值。
public class Main {
public static void main(String[] args) {
User user1 = new User("John");
User user2 = new User("Jane");
User user3 = new User("Doe");
}
}
class User {
private static int count;
private String name;
static {
count = 0;
}
{
System.out.println("非静态代码块执行");
}
public User(String name) {
System.out.println("构造器执行");
this.name = name;
count++;
}
public User() {
count++;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static int getCount() {
return count;
}
}
单例模式
单例模式是一种创建型设计模式,保证一个类只有一个实例,并提供一个全局访问点。
应用场景:线程池、数据库连接池、日志对象、共享的配置对象等。
饿汉式(提前创建实例)
public class Main {
public static void main(String[] args) {
A a = A.getInstance();
A b = A.getInstance();
System.out.println(a == b);
}
}
class A {
private static final A instance = new A();
private A() {
}
public void print() {
System.out.println("Hello");
}
public static A getInstance() {
return instance;
}
}
懒汉式(延迟创建实例)
public class Main {
public static void main(String[] args) {
var b1 = B.getInstance();
var b2 = B.getInstance();
System.out.println(b1 == b2); // true
}
}
class B {
private static B instance;
private B() {
}
public void print() {
System.out.println("Hello");
}
public static B getInstance() {
if (instance == null) {
instance = new B();
}
return instance;
}
}
继承
继承是面向对象的三大特性之一,用来描述类与类之间的关系。
继承的特点
- 子类可以继承父类的非私有成员(成员变量、方法、构造器、代码块、内部类)。
- Java中只支持单继承,一个类只能有一个父类。
- Java中支持多层继承,一个类可以有多个子类。
- Java中所有类都直接或间接继承自Object类。
权限修饰符
- private:只能在本类中访问。
- 缺省:不写,只能在同一个包中的类中访问。
- protected:本类、同一个包中的类、子孙类中可以访问。(子类中用父类访问是不行的)
- public:任何地方都可以访问。
修饰符 | 本类 | 同一个包中的类 | 子孙类 | 任意类 |
---|---|---|---|---|
private | √ | × | × | × |
缺省 | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
public class Main {
public static void main(String[] args) {
Fu fu = new Fu();
Zi zi = new Zi();
zi.publicMethod();
}
}
class Fu {
private void privateMethod() {
System.out.println("-----------privateMethod-----------");
}
void defaultMethod() {
System.out.println("-----------defaultMethod-----------");
}
protected void protectedMethod() {
System.out.println("-----------protectedMethod-----------");
}
public void publicMethod() {
System.out.println("-----------publicMethod-----------");
}
}
class Zi extends Fu {
public void test() {
// privateMethod(); // error
defaultMethod();
protectedMethod();
publicMethod();
}
}
方法重写
方法重写是指子类中可以根据需要对从父类继承来的方法进行重新编写。
- 子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限(public > protected > 缺省 )
- 重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
- 私有方法、静态方法不能被重写,如果重写会报错的。
public class Main {
public static void main(String[] args) {
Fu f = new Fu();
f.show("hello");
Zi z = new Zi();
z.show("hello");
}
}
class Fu {
public void show(String str) {
System.out.println("Fu show " + str);
}
}
class Zi extends Fu {
@Override
public void show(String str) {
System.out.println("Zi show " + str);
}
}
super关键字
super关键字是一个引用变量,用来访问父类的成员。
- super.成员变量:访问父类的成员变量。
- super.成员方法:访问父类的成员方法。
- super():访问父类的构造器。
public class Main {
public static void main(String[] args) {
Fu f = new Fu("李雷");
f.show("hello");
System.out.println(f.name);
Zi z = new Zi( "李敏");
z.show("hello");
System.out.println(z.name);
}
}
class Fu {
String name ;
Fu(String name) {
this.name = name;
}
public void show(String str) {
System.out.println("Fu show " + str);
}
}
class Zi extends Fu {
Zi(String name) {
super(name);
}
@Override
public void show(String str) {
System.out.println("Zi show " + str);
}
}
this调用构造器
public class Main {
public static void main(String[] args) {
Zi z = new Zi();
}
}
class Fu {
Fu() {
System.out.println("Fu constructor");
}
}
class Zi extends Fu {
Zi() {
this(10);
System.out.println("Zi constructor");
}
Zi(int i) {
System.out.println("Zi constructor with parameter");
}
}
多态
多态的概念
多态是面向对象的三大特性之一,指一个引用变量在不同情况下所表现出来的多种形态。
- 多态的前提:继承/实现关系、存在方法重写、父类引用指向子类对象。
- 多态的好处:提高了程序的扩展性。
- 多态的弊端:不能使用子类特有的方法。(可以通过向下转型解决)
package org.example;
public class Main {
public static void main(String[] args) {
// 对象的多态性
Animal dog = new Dog();
Animal cat = new Cat();
// 行为的多态性 编译看左边,运行看右边 前提是方法需要被重写
dog.run();
cat.run();
// 编译报错,因为Animal没有meow方法 Cannot resolve method 'meow' in 'Animal'
// cat.meow();
// 如果想调用子类特有的方法,需要向下转型
Cat c = (Cat) cat;
c.meow();
// 属性变量没有多态性 编译看左边,运行还是看左边
System.out.println(dog.name); // Animal
System.out.println(cat.name); // Animal
// 传入的参数是Animal类型,但是实际上是Dog和Cat对象,所以调用的是Dog和Cat的run方法
System.out.println("Animal run");
go(dog);
go(cat);
}
static void go(Animal animal) {
animal.run();
}
}
class Animal {
public String name = "Animal";
public void eat() {
System.out.println("Animal is eating");
}
public void run() {
System.out.println("Animal is running");
}
}
class Dog extends Animal {
public String name = "Dog";
public void bark() {
System.out.println("Dog is barking");
}
@Override
public void run() {
System.out.println("Dog is running");
}
}
class Cat extends Animal {
public String name = "Cat";
public void meow() {
System.out.println("Cat is meowing");
}
@Override
public void run() {
System.out.println("Cat is running");
}
}
多态的好处
- 在多态形式下,右边对象是解耦合的,更便于扩展和维护。
- 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。
多态下的类型转换
- 自动类型转换:父类引用指向子类对象,可以直接赋值。
Animal dog = new Dog();
- 强制类型转换:父类引用指向子类对象,需要强制类型转换。
Animal cat = new Cat(); Cat c = (Cat) cat;
强制类型转换时,需要注意类型转换异常:ClassCastException
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
// 向下转型
Cat c = (Cat) cat;
c.meow();
// 向下转型异常 ClassCastException
Dog d = (Dog) cat;
d.bark();
}
}
解决方法:使用instanceof关键字判断对象的类型
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
if (cat instanceof Cat) {
Cat c = (Cat) cat;
c.meow();
}
if (dog instanceof Dog) {
Dog d = (Dog) dog;
d.bark();
}
}
}
final关键字
final关键字是一个修饰符,可以修饰类、方法、变量。
- final修饰的类不能被继承。
- final修饰的方法不能被重写。
- final修饰的变量是常量,只能赋值一次。
final修饰类
public final class Dog {
public void bark() {
System.out.println("Dog is barking");
}
}
class Husky extends Dog {
// error: cannot inherit from final Dog
}
final修饰方法
public class Dog {
public final void bark() {
System.out.println("Dog is barking");
}
}
class Husky extends Dog {
// error: overridden method is final
public void bark() {
System.out.println("Husky is barking");
}
}
final修饰变量
public class Main {
public static void main(String[] args) {
final int a = 10;
// error: cannot assign a value to final variable a
a = 20;
}
}
final修饰引用变量
public class Main {
public static void main(String[] args) {
final Dog dog = new Dog();
dog.bark();
// error: cannot assign a value to final variable dog
dog = new Dog();
}
}
class Dog {
public void bark() {
System.out.println("Dog is barking");
}
}
final修饰类变量
public class Main {
public static void main(String[] args) {
System.out.println(Dog.NUMBER);
}
}
class Dog {
public static final int NUMBER;
static {
NUMBER = 10;
}
void setNumber(int number) {
// Error: cannot assign a value to final variable NUMBER
NUMBER = number;
}
}
常量
常量是指在程序运行过程中,值不会发生改变的量。
- 使用了static和final修饰的变量,称为常量。
好处
- 提高程序的可维护性。
- 程序编译后,常量会被"宏替换",提高程序的运行效率。
public class Main {
public static void main(String[] args) {
System.out.println(Dog.NUMBER);
}
}
class Dog {
public static final int NUMBER = 10;
}
验证
编译后直接查看class文件,常量会被替换为具体的值。
public class Main {
public static void main(String[] args) {
System.out.println(10);
}
}
枚举
枚举是一种特殊的类,用来表示固定个数的常量。
public class Main {
public static void main(String[] args) {
System.out.println(Season.SPRING); // SPRING
System.out.println(Season.SUMMER); // SUMMER
System.out.println(Season.AUTUMN); // AUTUMN
System.out.println(Season.WINTER); // WINTER
}
}
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
枚举的属性和方法
public class Main {
public static void main(String[] args) {
System.out.println(Season.SPRING); // SPRING
System.out.println(Season.SUMMER); // SUMMER
System.out.println(Season.AUTUMN); // AUTUMN
System.out.println(Season.WINTER); // WINTER
System.out.println(Season.SPRING.getName()); // Spring
System.out.println(Season.SUMMER.getName()); // Summer
System.out.println(Season.AUTUMN.getName()); // Autumn
System.out.println(Season.WINTER.getName()); // Winter
}
}
public enum Season {
SPRING("Spring"), SUMMER("Summer"), AUTUMN("Autumn"), WINTER("Winter");
private final String name;
Season(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public enum Color {
RED(255, 0, 0),
GREEN(0, 255, 0),
BLUE(0, 0, 255);
private final int r;
private final int g;
private final int b;
Color(int r, int g, int b) {
this.r = r;
this.g = g;
this.b = b;
}
public int getR() { return r; }
public int getG() { return g; }
public int getB() { return b; }
}
抽象类
在Java中有一个关键字叫:abstract,它就是抽象的意思,可以用它修饰类、成员方法。
abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
抽象类最主要的特点:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。
一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,我们设计这样的抽象类,就是为了更好的支持多态。
package org.example;
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.run();
Animal cat = new Cat();
cat.setName("Tom");
cat.run();
System.out.println(cat.getName());
}
}
abstract class Animal {
private String name;
public abstract void run();
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Dog extends Animal {
@Override
public void run() {
System.out.println("Dog is running");
}
}
class Cat extends Animal {
@Override
public void run() {
System.out.println("Cat is running");
}
}
抽象类,模板方法设计模式
解决方法中存在重复代码的问题
package org.example;
public class Main {
public static void main(String[] args) {
Person student = new Student();
student.write();
Person teacher = new Teacher();
teacher.write();
}
}
abstract class Person {
public final void write() {
System.out.println("标题:繁星之下");
content();
System.out.println("结尾:敬上");
}
public abstract void content();
}
class Student extends Person {
@Override
public void content() {
System.out.println("正文:在繁星之下,我看到了你");
}
}
class Teacher extends Person {
@Override
public void content() {
System.out.println("正文:在繁星之下,我看到了我自己");
}
}
接口
接口中的方法默认是public abstract的。
接口中的变量默认是public static final的。
可以同时实现多个接口 class A implements B,C
package org.example;
public class Main {
public static void main(String[] args) {
Person student = new Student();
student.write();
Person teacher = new Teacher();
teacher.write();
System.out.println(Person.name);
}
}
interface Person {
String name = "Person";
void write();
}
class Student implements Person {
@Override
public void write() {
System.out.println("学生写作业");
}
}
class Teacher implements Person {
@Override
public void write() {
System.out.println("老师批改作业");
}
}
接口之间多继承
package org.example;
interface A {
void testA();
}
interface B {
void testB();
}
interface C extends A, B {
void testC();
}
class D implements C {
@Override
public void testA() {
System.out.println("testA");
}
@Override
public void testB() {
System.out.println("testB");
}
@Override
public void testC() {
System.out.println("testC");
}
}
public class Main {
public static void main(String[] args) {
D d = new D();
d.testA();
d.testB();
d.testC();
}
}
接口的三种方法
package org.example;
interface A {
default void test() {
System.out.println("test"); // 默认方法 Java 8
test3();
}
static void test2() {
System.out.println("test2"); // 静态方法 Java 8
}
private void test3() {
System.out.println("test3"); // 私有方法 不需要实现 Java 9
}
void say();
}
class B implements A {
@Override
public void test() {
System.out.println("test B");
}
@Override
public void say() {
System.out.println("say");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.test();
A.test2();
}
}
接口、类、继承关系
- 一个类可以实现多个接口。
- 一个接口可以继承多个接口。
- 一个类可以继承一个类,并实现多个接口。
package org.example;
interface A {
default void test() {
System.out.println("test A");
}
}
interface B {
default void test() {
System.out.println("test B");
}
}
class C {
public void test() {
System.out.println("test C");
}
}
class D extends C implements A, B {
@Override
public void test() {
System.out.println("test D"); // test D
super.test(); // test C
B.super.test(); // test B
A.super.test(); // test A
}
}
public class Main {
public static void main(String[] args) {
D d = new D();
d.test();
}
}
内部类
成员内部类
package org.example;
public class Main {
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
Outer.Inner inner = outer.new Inner();
inner.show();
}
}
class Outer {
private int num = 10;
class Inner {
private int num = 20;
public void show() {
int num = 30;
System.out.println("inner class");
System.out.println(num); // 30
System.out.println(this.num); // 20
System.out.println(Outer.this.num); // 10
}
}
public void test() {
System.out.println("outer class");
Inner inner = new Inner();
inner.show();
}
}
静态内部类
package org.example;
public class Main {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.show();
}
}
class Outer {
private static int num = 10;
public void run() {
System.out.println("Outer run");
}
static class Inner {
private int num = 20;
public void show() {
System.out.println(num);
System.out.println(Outer.num);
Outer outer = new Outer();
outer.run();
}
}
}
局部内部内
public class Main {
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
}
}
class Outer {
private int num = 10;
public void test() {
// 鸡肋 一般不使用
class Inner {
private int num = 20;
public void show() {
System.out.println(num);
}
}
interface A {}
Inner inner = new Inner();
inner.show();
}
}
匿名内部类
就是一种特殊的局部内部类
特点:匿名内部类本质就是一个子类,并会立即创建出一个子类对象。 作用:用于更方便的创建一个子类对象。
package org.example;
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
@Override
void eat() {
System.out.println("Cat is eating");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
void eat() {
System.out.println("Eating");
}
};
animal.eat();
Animal cat = new Cat();
cat.eat();
}
}
匿名内部类用法
package org.example;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Hello World");
JPanel panel = new JPanel();
JButton button = new JButton("Click me");
// button action
// 使用匿名内部类 ActionListener 实现 button 点击事件
// button.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// System.out.println("Hello World");
// }
// });
button.addActionListener(e -> System.out.println("Hello World"));
panel.add(button);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
Arrays
Arrays类是Java中的一个工具类,提供了一系列静态方法,用于操作数组。
package org.example;
import java.util.Arrays;
import java.util.function.IntUnaryOperator;
public class Main {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 6, 5, 7, 8, 9, 10};
// 打印数组
System.out.println(Arrays.toString(arr));
// 排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
// 二分查找
System.out.println(Arrays.binarySearch(arr, 5));
// 填充
Arrays.fill(arr, 0);
System.out.println(Arrays.toString(arr));
// 比较
int[] arr2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
System.out.println(Arrays.equals(arr, arr2));
// 复制
int[] arr3 = Arrays.copyOf(arr, arr.length);
System.out.println(Arrays.toString(arr3));
// 复制指定长度
int[] arr4 = Arrays.copyOfRange(arr, 0, 5);
System.out.println(Arrays.toString(arr4));
// setAll
Arrays.setAll(arr, i -> i * 2);
System.out.println(Arrays.toString(arr));
// 匿名内部类
Arrays.setAll(arr, new IntUnaryOperator(){
@Override
public int applyAsInt(int operand) {
return operand * 4;
}
});
System.out.println(Arrays.toString(arr));
}
}
Arrays.sort
package org.example;
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
Student[] students = {
new Student("Aka", 22, 90),
new Student("Alice", 18, 100),
new Student("Bob", 20, 70),
new Student("Aob", 20, 70),
};
// Sort by name
Arrays.sort(students, (s1, s2) -> s1.getName().compareTo(s2.getName()));
System.out.println(Student.arrayToString(students));
// Sort by age
Arrays.sort(students, (s1, s2) -> s1.getAge() - s2.getAge());
System.out.println(Student.arrayToString(students));
// 匿名内部类 Sort by score
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.getScore() - s2.getScore();
}
});
System.out.println(Student.arrayToString(students));
// 默认排序
Arrays.sort(students);
System.out.println(Student.arrayToString(students));
}
}
class Student implements Comparable<Student> {
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getScore() {
return score;
}
static String arrayToString(Student[] students) {
StringBuilder sb = new StringBuilder();
for (Student student : students) {
// [Alice, 18, 80]
sb.append(" [").append(student.getName()).append(", ").append(student.getAge()).append(", ").append(student.getScore()).append("] ");
}
return sb.toString();
}
@Override
public int compareTo(Student o) {
// o 为第二个对象
// 官方规定:返回负数表示当前对象比 o 小 ;返回正数表示当前对象比 o 大,大往后排,小往前排;返回 0 表示相等
return this.name.compareTo(o.name);
}
}
Lambda
Lambda表达式是JDK 8开始新增的一种语法形式;作用:用于简化函数式接口匿名内部类的代码写法。
函数式接口: 只有一个抽象方法的接口
package org.example;
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
Student[] students = {
new Student("Aka", 22, 90),
new Student("Alice", 18, 100),
new Student("Bob", 20, 70),
new Student("Aob", 20, 70),
};
// Sort by name
Arrays.sort(students, (s1, s2) -> s1.getName().compareTo(s2.getName()));
System.out.println(Student.arrayToString(students));
// Sort by age
Arrays.sort(students, (s1, s2) -> s1.getAge() - s2.getAge());
System.out.println(Student.arrayToString(students));
// 匿名内部类 Sort by score
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.getScore() - s2.getScore();
}
});
System.out.println(Student.arrayToString(students));
// 默认排序
Arrays.sort(students);
System.out.println(Student.arrayToString(students));
}
}
class Student implements Comparable<Student> {
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getScore() {
return score;
}
static String arrayToString(Student[] students) {
StringBuilder sb = new StringBuilder();
for (Student student : students) {
// [Alice, 18, 80]
sb.append(" [").append(student.getName()).append(", ").append(student.getAge()).append(", ").append(student.getScore()).append("] ");
}
return sb.toString();
}
@Override
public int compareTo(Student o) {
// o 为第二个对象
// 官方规定:返回负数表示当前对象比 o 小 ;返回正数表示当前对象比 o 大,大往后排,小往前排;返回 0 表示相等
return this.name.compareTo(o.name);
}
}
方法引用
方法引用是一种函数式接口的实现方式,可以简化Lambda表达式。
- 方法引用是Lambda表达式的一种简写形式。
- 方法引用的前提是Lambda表达式中只有一行代码。
package org.example;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Student[] students = {
new Student("Aka", 22, 90),
new Student("Alice", 18, 100),
new Student("Bob", 20, 70),
new Student("Aob", 20, 70),
};
// Sort by name
Arrays.sort(students, (s1, s2) -> s1.getName().compareTo(s2.getName()));
System.out.println(Student.arrayToString(students));
// Sort by age
Arrays.sort(students, (s1, s2) -> s1.getAge() - s2.getAge());
System.out.println(Student.arrayToString(students));
// // 匿名内部类 Sort by score
// Arrays.sort(students, new Comparator<Student>() {
// @Override
// public int compare(Student s1, Student s2) {
// return s1.getScore() - s2.getScore();
// }
// });
// System.out.println(Student.arrayToString(students));
// 1. 静态方法引用 Sort by score
Arrays.sort(students, Student::compareByScore);
System.out.println(Student.arrayToString(students));
// 2. 实例方法引用 Sort by age
Student s = new Student("Aka", 22, 90);
Arrays.sort(students, s::compareByAge);
System.out.println(Student.arrayToString(students));
// 默认排序
Arrays.sort(students);
System.out.println(Student.arrayToString(students));
}
}
class Student implements Comparable<Student> {
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getScore() {
return score;
}
static String arrayToString(Student[] students) {
StringBuilder sb = new StringBuilder();
for (Student student : students) {
// [Alice, 18, 80]
sb.append(" [").append(student.getName()).append(", ").append(student.getAge()).append(", ").append(student.getScore()).append("] ");
}
return sb.toString();
}
@Override
public int compareTo(Student o) {
// o 为第二个对象
// 官方规定:返回负数表示当前对象比 o 小 ;返回正数表示当前对象比 o 大,大往后排,小往前排;返回 0 表示相等
return this.name.compareTo(o.name);
}
static int compareByScore(Student s1, Student s2) {
return s1.getScore() - s2.getScore();
}
public int compareByAge(Student s1, Student s2) {
return s1.getAge() - s2.getAge();
}
}
特定类型的方法引用
package org.example;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String[] names = {"John", "Jane", "Adam", "Tom", "Jerry","ada","jbk"};
{
String[] copy = Arrays.copyOf(names, names.length);
// Sort the array By name string
Arrays.sort(copy);
System.out.println("Sorted names: " + Arrays.toString(copy));
}
{
String[] copy = Arrays.copyOf(names, names.length);
// Sort the array By name ignoring case
Arrays.sort(copy, String.CASE_INSENSITIVE_ORDER);
System.out.println("Sorted names ignoring case: " + Arrays.toString(copy));
}
{
String[] copy = Arrays.copyOf(names, names.length);
// Sort the array By name ignoring case
Arrays.sort(copy, (a, b) -> a.compareToIgnoreCase(b));
System.out.println("Sorted names ignoring case: " + Arrays.toString(copy));
}
{
String[] copy = Arrays.copyOf(names, names.length);
// Sort the array By name ignoring case
Arrays.sort(copy, String::compareToIgnoreCase);
System.out.println("Sorted names ignoring case: " + Arrays.toString(copy));
}
}
}
构造器引用
package org.example;
public class Main {
public static void main(String[] args) {
CreateCar Ccar = new CreateCar() {
@Override
public Car create(String name) {
return new Car(name);
}
};
CreateCar Ccar1 = (name) -> new Car(name);
// 构造器引用
CreateCar Ccar2 = Car::new;
}
}
@FunctionalInterface
interface CreateCar {
Car create(String name);
}
class Car {
private String name;
Car(String name){
this.name = name;
}
}