IDEA常用快捷

main方法 ——> psvm

多行注释 ——-> Ctrl+Shift+/

格式化代码 ——> Ctrl +Alt+L

生成左边变量 ——> ctrl+Alt+V

查看类结构 —-> Alt+7

数组

  1. public class Test01 {
  2. public static void main(String[] args) {
  3. int[] arr1 = new int[2];
  4. arr1[0] = 100;
  5. arr1[1] = 200;
  6. int[] arr2 = arr1;
  7. arr2[0] = 1;
  8. arr2[1] = 2;
  9. System.out.println(arr1); //打印地址
  10. System.out.println(arr1[0]);
  11. System.out.println(arr2);
  12. System.out.println(arr2[0]);
  13. int[] arr3 = {1,2};
  14. System.out.println(arr3[0]);
  15. System.out.println(arr3[1]);
  16. }
  17. }

方法的重载

  • 同一类中
  • 方法名相同
  • 参数不同(类型或者数量)
  • 与返回类型无关
  • 根据输入的参数,区分调用的方法
  1. public class Test02 {
  2. public static void main(String[] args) {
  3. System.out.println(sum(10,20));
  4. System.out.println(sum(10.0,20.0));
  5. int i = sum(1,2,3);
  6. System.out.println(i);
  7. }
  8. public static int sum(int a,int b){
  9. return a+b;
  10. }
  11. public static int sum(int a,int b,int c){
  12. return a+b+c;
  13. }
  14. public static double sum(double a,double b){
  15. return a+b;
  16. }
  17. }

方法参数传递

对于基本数据类型的参数,形式参数的改变,不会影响实参的值

  1. public class Test03 {
  2. public static void main(String[] args) {
  3. int number = 100;
  4. change(number);
  5. System.out.println(number); //100
  6. }
  7. private static void change(int number) {
  8. number = 200;
  9. }
  10. }

对于引用数据类型的参数,形式参数的改变,将会影响实参的值

  1. public class Test03 {
  2. public static void main(String[] args) {
  3. int[] arr={1,2,3};
  4. change(arr);
  5. System.out.println(arr[0]); //10
  6. }
  7. private static void change(int[] arr) {
  8. arr[0] = 10;
  9. }
  10. }

输出

System.out.print() 不换行

  1. int[] arr3 = {1,2,3,4,5};
  2. for (int i=0;i<arr3.length;i++){
  3. System.out.print(arr3[i]+",");
  4. }

输入

  1. Scanner sc = new Scanner(System.in);
  2. System.out.println("请输入a:");
  3. int a = sc.nextInt();
  4. System.out.println("输入的a为:"+a);

逢7过

  1. for (int i = 1;i<100;i++){
  2. if (i%7==0||i%10==7||i/10==7){
  3. System.out.println("过");
  4. }else{
  5. System.out.print(i+"\0");
  6. }
  7. }

1 2 3 4 5 6 过
8 9 10 11 12 13 过
15 16 过
18 19 20 过
22 23 24 25 26 过

29 30 31 32 33 34 过
36 过
38 39 40 41 过
43 44 45 46 过
48 过
50 51 52 53 54 55 过

58 59 60 61 62 过
64 65 66 过
68 69 过









80 81 82 83 过
85 86 过
88 89 90 过
92 93 94 95 96 过

99

类调用

成员变量 ——-> 方法之外

class Test02

  1. public class Test02 {
  2. public static void main(String[] args) {
  3. System.out.println(sum(10,20));
  4. System.out.println(sum(10.0,20.0));
  5. int i = sum(1,2,3);
  6. System.out.println(i);
  7. }
  8. int age = 18;
  9. public static int sum(int a,int b){
  10. return a+b;
  11. }
  12. public static int sum(int a,int b,int c){
  13. return a+b+c;
  14. }
  15. public static double sum(double a,double b){
  16. return a+b;
  17. }
  18. }

class Test3

  1. public static void main(String[] args) {
  2. Test02 t2 = new Test02();
  3. System.out.println(t2.sum(2, 3));
  4. System.out.println(t2.age);
  5. }

指向相同

  1. public static void main(String[] args) {
  2. Test02 t2 = new Test02();
  3. System.out.println(t2.age); //18
  4. Test02 t1 = t2;
  5. t1.age = 20;
  6. System.out.println(t1.age); //20
  7. System.out.println(t2.age); //20
  8. }

变量

java基础 - 图1

封装private

以private封装成员变量,提供get/set方法供它类访问变量和修改变量,它类不可直接访问成员变量

class Test02

  1. private int age;

以下访问将报错

  1. Test02 t2 = new Test02();
  2. System.out.println(t2.age);

正确访问,调用对应的get方法

  1. Test02 t2 = new Test02();
  2. System.out.println(t2.getAge()); //0

构造方法

  1. //无参
  2. public Test02() {
  3. }
  4. //带参
  5. public Test02(int age, String name) {
  6. this.age = age;
  7. this.name = name;
  8. }
  1. public class Test03 {
  2. public static void main(String[] args) {
  3. //无参创建对象,默认0
  4. Test02 t2 = new Test02();
  5. System.out.println(t2.getAge()); //0
  6. Test02 t3 = new Test02(30,"名字");
  7. System.out.println(t3.getAge()+","+t3.getName()); //30,名字
  8. }
  9. }

字符串

  1. public static void main(String[] args) {
  2. char[] chr = {'a', 'b', 'c'};
  3. String s1 = new String(chr);
  4. String s2 = new String(chr);
  5. System.out.println(s1 == s2); //比较地址 false
  6. String a = "abc";
  7. String b = "abc";
  8. System.out.println(a == b); //true
  9. String s3 = new String("abc");
  10. String s4 = new String("abc");
  11. System.out.println(s3 == s4); //false
  12. }

添加和反转

  1. public static void main(String[] args) {
  2. StringBuilder sb = new StringBuilder();
  3. sb.append("Hello").append(" ").append("world");
  4. System.out.println(sb);
  5. sb.reverse();
  6. System.out.println(sb);
  7. }

Hello world
dlrow olleH

反转

  1. public static void main(String[] args) {
  2. Scanner sc = new Scanner(System.in);
  3. System.out.print("请输入字符:");
  4. String line = sc.nextLine();
  5. String s = ToReverse(line);
  6. System.out.println(s);
  7. }
  8. private static String ToReverse(String line) {
  9. return new StringBuilder().append(line).reverse().toString();
  10. }

ArrayList相关方法

  1. public static void main(String[] args) {
  2. ArrayList<String> arrayList = new ArrayList<>();
  3. arrayList.add("hello");
  4. arrayList.add("world");
  5. System.out.println(arrayList); //[hello, world]
  6. arrayList.add(0,"java"); //指定索引处添加
  7. System.out.println(arrayList); //[java, hello, world]
  8. }
  1. public static void main(String[] args) {
  2. ArrayList<String> arrayList = new ArrayList<>();
  3. arrayList.add("hello");
  4. arrayList.add("world");
  5. System.out.println(arrayList);
  6. arrayList.add(0,"java"); //指定索引处添加
  7. System.out.println(arrayList);
  8. int size = arrayList.size();
  9. System.out.println(size);
  10. /*
  11. boolean hello = arrayList.remove("Hello");
  12. System.out.println(hello); //false
  13. boolean hello1 = arrayList.remove("hello");
  14. System.out.println(hello1); //true
  15. String remove = arrayList.remove(0);
  16. System.out.println(remove);
  17. */
  18. String set = arrayList.set(0, "修改了0索引的元素");
  19. System.out.println("返回被修改的元素"+set);
  20. System.out.println(arrayList);
  21. System.out.println(arrayList.get(0));
  22. }

Arraylist的遍历

结果相同

  1. public static void main(String[] args) {
  2. ArrayList<String> arrayList = new ArrayList<>();
  3. arrayList.add("hello");
  4. arrayList.add("world");
  5. System.out.println(arrayList);
  6. arrayList.add(0,"java"); //指定索引处添加
  7. //方式一
  8. for (String arrayList1:arrayList){
  9. System.out.println(arrayList1);
  10. }
  11. //方式二
  12. for (int i = 0;i<arrayList.size();i++){
  13. System.out.println(arrayList.get(i));
  14. }
  15. }
  1. public static void main(String[] args) {
  2. ArrayList<Test02> arrayList = new ArrayList<>();
  3. Test02 t1 = new Test02(30,"张三");
  4. Test02 t2 = new Test02(26,"李四");
  5. Test02 t3 = new Test02(14,"王五");
  6. arrayList.add(t1);
  7. arrayList.add(t2);
  8. arrayList.add(t3);
  9. //方式一
  10. for (Test02 arrayList1:arrayList){
  11. System.out.println(arrayList1.getAge()+","+arrayList1.getName());
  12. }
  13. //方式二
  14. for (int i = 0;i<arrayList.size();i++){
  15. System.out.println(arrayList.get(i).getAge());
  16. }
  17. }

继承

Test02

  1. public class Test02 {
  2. private int num = 20;
  3. int number = 10;
  4. public void t2(){
  5. System.out.println("test2");
  6. }
  7. }

Test03

  1. public class Test03 extends Test02 {
  2. public void t3(){
  3. System.out.println("Test03");
  4. }
  5. public static void main(String[] args) {
  6. Test03 t3 = new Test03();
  7. t3.t3();
  8. t3.t2(); //父类中的方法
  9. System.out.println(t3.number); //父类中的变量
  10. //但是不可直接访问 num变量,因为num被private保护
  11. }
  12. }

Test03
test2
10

  • 使子类可以调用父类中的方法和变量
  • 如子类与父类含有相同的方法,优先调用子类的方法

this关键字与super关键字

  1. public class Test01 {
  2. int age = 8;
  3. public static void main(String[] args) {
  4. Test01 test01 = new Test01();
  5. test01.show();
  6. }
  7. public void show(){
  8. int age = 10;
  9. System.out.println(age); //10
  10. System.out.println(this.age); //8
  11. }
  12. }
  1. public class Test03 extends Test01 {
  2. int age = 12;
  3. public void t3(){
  4. int age = 1;
  5. System.out.println("Test03");
  6. System.out.println(age); //1
  7. System.out.println(this.age); //12
  8. System.out.println(super.age); //8
  9. }
  10. public static void main(String[] args) {
  11. Test03 test03 = new Test03();
  12. test03.t3();
  13. }
  14. }

继承中构造方法访问特点

  1. public class Fu {
  2. public Fu(){
  3. System.out.println("Fu无参构造方法");
  4. }
  5. public Fu(int age){
  6. System.out.println("Fu带参构造方法");
  7. }
  8. }
  1. public class Zi extends Fu {
  2. public Zi(){
  3. super(); //默认的访问无参构造方法,可省
  4. System.out.println("Zi无参构造方法");
  5. }
  6. public Zi(int age){
  7. super(); //默认的访问无参构造方法,可省
  8. System.out.println("Zi带参构造方法");
  9. }
  10. }
  1. public static void main(String[] args) {
  2. Zi zi = new Zi();
  3. Zi zi1 = new Zi(18);
  4. }

Fu无参构造方法
Zi无参构造方法
Fu无参构造方法
Zi带参构造方法

都将先调用父类的无参构造方法,

原因:子类的构造方法默认将先访问父类的构造方法,因为子类继承父类,可能会使用到父类中的数据,所以子类初始化之前,一定要完成父类数据的初始化.

调用父类中带参构造方法

如果父类中没有 —> 无参构造方法,想让其子类访问带参构造方法

使用 super(1); //访问带参构造方法

  1. public Zi(){
  2. super(1); //访问带参构造方法
  3. System.out.println("Zi无参构造方法");
  4. }
  5. public Zi(int age){
  6. super(1);
  7. System.out.println("Zi带参构造方法");
  8. }

Fu带参构造方法
Zi无参构造方法
Fu带参构造方法
Zi带参构造方法

在父类中添加无参构造方法(常用)

子类父类方法同名

super.show(); //调用父类中的show方法

  1. public class Fu {
  2. public void show(){
  3. System.out.println("FuZ中show");
  4. }
  5. }
  1. public class Zi extends Fu {
  2. public void show(){
  3. System.out.println("Zi中show");
  4. }
  5. public void show_FU(){
  6. super.show();
  7. }
  8. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Zi zi = new Zi();
  4. zi.show();
  5. zi.show_FU();
  6. }
  7. }

Zi中show
FuZ中show

方法的重写

如果父类中的方法修饰符为 private 或final 修饰的方法,则此方法不可被重写

且子类 方法修饰符范围需大于 父类中的方法修饰符

范围大小 public > 默认的(即不写修饰符) > private

  1. public class Fu {
  2. public void show(){
  3. System.out.println("FuZ中show");
  4. }
  5. }
  1. public class Zi extends Fu {
  2. @Override //标注方法为父类中重写的方法
  3. public void show(){
  4. System.out.println("show方法重写");
  5. super.show();
  6. }
  7. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Zi zi = new Zi();
  4. zi.show();
  5. }
  6. }

关键词final

修饰在类或方法或变量上,修饰后将不可被更改

  1. public final class Zi {
  2. final int age=10; //修饰在成员变量上,必须给出初始值
  3. public final void show(){
  4. System.out.println("final关键字");
  5. }
  6. }

引用类型:

表示地址不能被修改,所以值能能修改成功

  1. public static void main(String[] args) {
  2. final Fu fu = new Fu();
  3. fu.arrayList.add("hello");
  4. System.out.println(fu.arrayList.get(0));
  5. fu = new Fu(); //将报错
  6. }

去除final正常运行

  1. public static void main(String[] args) {
  2. Fu fu = new Fu();
  3. fu.arrayList.add("hello");
  4. System.out.println(fu.arrayList.get(0));
  5. fu = new Fu();
  6. int size = fu.arrayList.size();
  7. System.out.println(size);
  8. }

static关键字

被static修饰的,可直接通过类名访问

被类的所有对象共享

  1. public class Zi {
  2. public String name;
  3. public static int age;
  4. public void show(){
  5. System.out.println(name+","+age);
  6. }
  7. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Zi.age = 100; //通过类名访问
  4. Zi zi = new Zi();
  5. zi.name = "张三";
  6. zi.show();
  7. Zi zi1 = new Zi();
  8. zi.name = "李四";
  9. zi.show();
  10. }
  11. }

类所有的对象共享,即所有对象的age都为100了

张三,100
李四,100

被static修饰的方法 只能访问静态方法和变量

  1. public class Zi {
  2. public String name;
  3. public static int age;
  4. public void show(){
  5. System.out.println(name);
  6. System.out.println(age); //调用静态变量
  7. show1(); //调用静态方法
  8. show(); //调用自己
  9. }
  10. public static void show1(){
  11. System.out.println(name); //报错
  12. System.out.println(age); //调用静态变量
  13. show1(); //调用静态方法
  14. show(); //报错
  15. }
  16. }

多态

同一对象在不同时刻表现出的不同状态

前提

  • 继承/接口
  • 方法重写
  • 有父类引用指向子类对象

Fu fu = new Zi(); //父类引用指向子类对象

编译看左边,运行看右边

多态的形式:

  • 具体类多态
  • 抽象类多态
  • 接口多态
  1. public class Animal {
  2. static int age = 4;
  3. public void eat(){
  4. System.out.println("动物");
  5. }
  6. }
  1. public class Cat extends Animal {
  2. static int age = 3;
  3. public String name = "小猫";
  4. @Override
  5. public void eat() {
  6. System.out.println("猫");
  7. }
  8. public void playgame(){
  9. System.out.println("玩毛线");
  10. }
  11. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. //父类引用指向子类
  4. Animal animal = new Cat();
  5. System.out.println(animal.age); //输出父类定义的成员变量值--> 4 行为多态,变量不多态
  6. //无法调用子类中特有的变量 name
  7. animal.eat(); //输出重写后方法的内容,即子类的方法--> 猫
  8. /*
  9. 虽然输出的是子类方法中的内容,但是不可调用父类中不存在的方法
  10. 为什么输出的是子类方法中的内容?
  11. 因为父类的方法被重写了
  12. */
  13. }
  14. }

分割线


  1. public class Fu {
  2. public void eat(){
  3. System.out.println("FU类方法");
  4. }
  5. }
  1. public class Zi extends Fu {
  2. @Override
  3. public void eat() {
  4. System.out.println("ZI类重写方法");
  5. }
  6. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Fu fu = new Zi(); //父类引用指向子类对象
  4. fu.eat();
  5. Fu fu1 = new Fu();
  6. fu1.eat();
  7. }
  8. }

ZI类重写方法
FU类方法

多态的好处

使用父类作形参,使用子类作实参,提高程序扩展性

缺点:不能访问子类所特有的方法

  1. public class Animal {
  2. public void eat(){
  3. System.out.println("动物");
  4. }
  5. }
  1. public class AnimalOperator {
  2. /*
  3. public void userAnimal(Cat c){
  4. c.eat();
  5. }
  6. public void userAnimal(Dog d){
  7. d.eat();
  8. }
  9. */
  10. public void userAnimal(Animal a){
  11. //Animal a = new Cat();
  12. //Animal a = new Dog();
  13. a.eat();
  14. }
  15. }
  1. public class Cat extends Animal {
  2. @Override
  3. public void eat() {
  4. System.out.println("猫的eat方法");
  5. }
  6. }
  1. public class Dog extends Animal {
  2. @Override
  3. public void eat() {
  4. System.out.println("狗吃粑粑");
  5. }
  6. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. AnimalOperator animalOperator = new AnimalOperator();
  4. Cat cat = new Cat();
  5. animalOperator.userAnimal(cat);
  6. Dog dog = new Dog();
  7. animalOperator.userAnimal(dog);
  8. }
  9. }

ZI类重写方法
Nu类重写方法

多态中的转型

在ZI类添加方法

  1. public void special(){
  2. System.out.println("俺是ZI类特有的方法");
  3. }

main方法中添加测试

  1. Fu f = new Zi(); //向上转型 子转父
  2. Zi z1 = (Zi)f; //向下转型 父转子
  3. z1.special(); //俺是ZI类特有的方法

分割线


  1. public class Animal {
  2. public void eat(){
  3. System.out.println("动物");
  4. }
  5. }
  1. public class Cat extends Animal {
  2. @Override
  3. public void eat() {
  4. System.out.println("猫的eat方法");
  5. }
  6. public void play(){
  7. System.out.println("猫玩毛线团");
  8. }
  9. }
  1. /*
  2. 多态的转型
  3. */
  4. public class Demo {
  5. public static void main(String[] args) {
  6. Animal animal = new Cat(); //向上转型
  7. animal.eat();
  8. //访问子类特有的方法
  9. //方式一
  10. Cat cat1 = new Cat();
  11. cat1.play();
  12. //方式二
  13. //不用创建新的对象
  14. Cat cat2 = (Cat)animal; //向下转型
  15. cat2.play();
  16. animal = new Dog();
  17. animal.eat();
  18. }
  19. }

输出:

猫的eat方法
猫玩毛线团

猫玩毛线团

狗吃粑粑

小案例

  1. public class Animal {
  2. private String name;
  3. private int age;
  4. public Animal() {
  5. }
  6. //需父类创建带参构造方法,子类才可创建带参构造方法
  7. public Animal(String name, int age) {
  8. this.name = name;
  9. this.age = age;
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public int getAge() {
  18. return age;
  19. }
  20. public void setAge(int age) {
  21. this.age = age;
  22. }
  23. public void eat(){
  24. System.out.println("动物吃肉");
  25. }
  26. }
  1. public class Dog extends Animal {
  2. public Dog() {
  3. }
  4. public Dog(String name, int age) {
  5. super(name, age);
  6. }
  7. @Override
  8. public void eat() {
  9. System.out.println("狗吃粑粑");
  10. }
  11. }
  1. public class Cat extends Animal {
  2. public Cat() {
  3. }
  4. public Cat(String name, int age) {
  5. super(name, age);
  6. }
  7. @Override
  8. public void eat() {
  9. System.out.println("猫猫吃鱼");
  10. }
  11. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Animal a = new Cat(); //无参构造
  4. a.setName("加非");
  5. a.setAge(9);
  6. System.out.println(a.getName()+","+a.getAge());
  7. a.eat();
  8. a = new Cat("梦琪",12); //带参构造
  9. System.out.println(a.getName()+","+a.getAge());
  10. a.eat();
  11. a = new Dog("旺财",18);
  12. System.out.println(a.getName()+","+a.getAge());
  13. a.eat();
  14. }
  15. }

加非,9
猫猫吃鱼
梦琪,12
猫猫吃鱼
旺财,18
狗吃粑粑

abstract关键字

一个方法没有方法体,应该被定义为抽象方法;而含有抽象方法的类,应被定义为抽象类

抽象类可以没有抽象方法,但无意义

  • 限定子类必须重写 父抽象类中的 抽象方法
  • 有构造方法 ,但是不能直接实例化,用于子类数据的初始化
  • 抽象方法只能在抽象类中创建,但是抽象类中可以没有抽象方法
  • 子类要不重写父类的抽象方法,要不子类也为抽象类
  1. /*
  2. 抽象类
  3. */
  4. public abstract class Animal {
  5. public abstract void eat();
  6. public void sleep(){
  7. System.out.println("动物想睡觉");
  8. }
  9. }
  1. public class Cat extends Animal {
  2. @Override
  3. public void eat() {
  4. System.out.println("猫猫吃鱼鱼");
  5. }
  6. /*
  7. public void sleep(){
  8. System.out.println("猫也要睡觉");
  9. }
  10. */
  11. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Animal a = new Cat();
  4. a.eat();
  5. a.sleep();
  6. }
  7. }

猫猫吃鱼鱼
动物想睡觉

  1. /*
  2. 抽象类
  3. */
  4. public abstract class Animal {
  5. private int age = 20;
  6. private final String city = "武汉";
  7. //构造方法,用于子类访问父类初始化数据
  8. public Animal() {
  9. }
  10. public Animal(int age) {
  11. this.age = age;
  12. }
  13. public void show() {
  14. age = 40;
  15. System.out.println(age + "," + city);
  16. }
  17. public abstract void eat();
  18. }

小案例

  1. /*
  2. 抽象类
  3. */
  4. public abstract class Animal {
  5. private String name;
  6. private int age;
  7. public Animal() {
  8. }
  9. public Animal(String name, int age) {
  10. this.name = name;
  11. this.age = age;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public int getAge() {
  20. return age;
  21. }
  22. public void setAge(int age) {
  23. this.age = age;
  24. }
  25. public abstract void eat();
  26. }
  1. public class Dog extends Animal {
  2. public Dog() {
  3. }
  4. public Dog(String name, int age) {
  5. super(name, age);
  6. }
  7. @Override
  8. public void eat() {
  9. System.out.println("狗狗吃粑粑");
  10. }
  11. }
  1. public class Cat extends Animal {
  2. public Cat() {
  3. }
  4. public Cat(String name, int age) {
  5. super(name, age);
  6. }
  7. @Override
  8. public void eat() {
  9. System.out.println("猫猫吃鱼鱼");
  10. }
  11. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Animal a = new Cat("加菲猫",12);
  4. System.out.println(a.getName()+","+a.getAge());
  5. a.eat();
  6. a = new Dog("旺财",10);
  7. System.out.println(a.getName()+","+a.getAge());
  8. a.eat();
  9. }
  10. }

加菲猫,12
猫猫吃鱼鱼
旺财,10
狗狗吃粑粑

接口interface

接口默认常量,即默认使用final修饰过,不可再次赋值

主要对行为进行抽象,无构造方法

所有类直接或间接指向父类 Object类,

JDK8和JDK9对接口有新特性

一个类可以实现多个接口

且一个接口可以继承多个接口

  • 默认修饰符 public static final
  • 没有构造方法
  • 默认方法修饰符 public abstract ,无方法体

以下两种相同

  1. public static final int age = 30;
  2. int age = 30;
  1. public abstract void eat();
  2. void eat();

java基础 - 图2

抽象类是对事物的抽象,接口是对行为的抽象

接口实现类implements

要么重写接口中的所有抽象方法,要么是抽象类

访问特点

  1. /*
  2. 接口类
  3. */
  4. public interface Jumpping{
  5. int num = 10;
  6. int num2 = 20;
  7. void eat();
  8. }
  1. /*
  2. 接口实现类
  3. */
  4. public class Cat implements Jumpping {
  5. @Override
  6. public void eat() {
  7. System.out.println("猫吃奶");
  8. }
  9. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Jumpping j = new Cat();
  4. System.out.println(j.num);
  5. j.eat();
  6. System.out.println(Jumpping.num2); //可直接使用接口名访问,因为默认使用static修饰
  7. }
  8. }

小案例

  1. public abstract class Animal {
  2. private String name;
  3. private int age;
  4. public Animal() {
  5. }
  6. public Animal(String name, int age) {
  7. this.name = name;
  8. this.age = age;
  9. }
  10. public String getName() {
  11. return name;
  12. }
  13. public void setName(String name) {
  14. this.name = name;
  15. }
  16. public int getAge() {
  17. return age;
  18. }
  19. public void setAge(int age) {
  20. this.age = age;
  21. }
  22. public abstract void eat();
  23. }
  1. public interface Jumpping{
  2. void jump();
  3. }
  1. public class Dog extends Animal implements Jumpping {
  2. public Dog() {
  3. }
  4. public Dog(String name, int age) {
  5. super(name, age);
  6. }
  7. @Override
  8. public void eat() {
  9. System.out.println("狗吃粑粑");
  10. }
  11. @Override
  12. public void jump() {
  13. System.out.println("狗能跳的更高了");
  14. }
  15. }
  1. /*
  2. 接口实现 类继承
  3. */
  4. public class Cat extends Animal implements Jumpping {
  5. public Cat() {
  6. }
  7. public Cat(String name, int age) {
  8. super(name, age);
  9. }
  10. @Override
  11. public void eat() {
  12. System.out.println("猫吃奶");
  13. }
  14. @Override
  15. public void jump() {
  16. System.out.println("猫学会了跳高");
  17. }
  18. }
  1. /*
  2. 测试类
  3. */
  4. public class Demo {
  5. public static void main(String[] args) {
  6. //接口中无法调用get/set方法,所以常用的还是具体类实现
  7. Jumpping j = new Cat();
  8. j.jump();
  9. j = new Dog();
  10. j.jump();
  11. //常用de,可以调用更多的方法
  12. Cat cat = new Cat();
  13. cat.eat();
  14. cat.jump();
  15. System.out.println(cat.getName()+","+cat.getAge());
  16. Animal a = new Cat("加菲猫",12);
  17. System.out.println(a.getName()+","+a.getAge());
  18. a.eat();
  19. }
  20. }

猫学会了跳高
狗能跳的更高了
猫吃奶
猫学会了跳高
null,0
加菲猫,12
猫吃奶

内部类

访问特点

  • 内部类可直接访问外部类的成员,包括私有
  • 外部类要访问内部类的成员,必须创建对象
  1. /*
  2. 外部类
  3. */
  4. public class Outer {
  5. private int num = 10;
  6. /*
  7. 成员内部类,注意:使用public修饰不常用,常使用private
  8. */
  9. public class Inner{
  10. public void show(){
  11. System.out.println(num); //内部可直接访问外部私有变量
  12. }
  13. }
  14. public void method(){
  15. /*
  16. 局部内部类,定义在类方法中
  17. */
  18. class Inner{
  19. public void show(){
  20. System.out.println(num);
  21. }
  22. }
  23. Inner i = new Inner();
  24. i.show(); //外部访问需创建对象
  25. }
  26. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Outer.Inner oi = new Outer().new Inner(); //创建内部类对象
  4. oi.show();
  5. }
  6. }

当修饰符变为private时不可直接访问

但外部类对象可访问内部类对象,所以我们可通过外部类对象间接访问内部类

  1. private class Inner{
  2. public void show(){
  3. System.out.println(num); //内部可直接访问外部私有变量
  4. }
  5. }
  1. public void method(){
  2. Inner i = new Inner();
  3. i.show(); //外部访问需创建对象
  4. }
  1. Outer o = new Outer();
  2. o.method(); //输出num的值

局部内部类

  1. /*
  2. 外部类
  3. */
  4. public class Outer {
  5. private int num = 10;
  6. /*
  7. 成员内部类
  8. */
  9. private class Inner{
  10. public void show(){
  11. System.out.println(num); //内部可直接访问外部私有变量
  12. }
  13. }
  14. public void method(){
  15. /*
  16. 局部内部类
  17. */
  18. int num2 = 20;
  19. class Inner1{
  20. public void show(){
  21. System.out.println(num2);
  22. System.out.println("局部内部类方法");
  23. }
  24. }
  25. Inner i = new Inner();
  26. i.show(); //外部访问需创建对象
  27. Inner1 i1 = new Inner1();
  28. i1.show(); //局部内部类访问
  29. }
  30. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. /*
  4. Outer.Inner oi = new Outer().new Inner();
  5. oi.show();
  6. */
  7. Outer o = new Outer();
  8. o.method();
  9. }
  10. }

10

20

局部内部类方法

匿名内部类

java基础 - 图3

  1. public interface Inter {
  2. void show();
  3. }
  1. /*
  2. 外部类
  3. */
  4. public class Outer {
  5. public void method(){
  6. /*
  7. 匿名内部类
  8. 本质:一个没有名字的对象
  9. */
  10. new Inter(){
  11. @Override
  12. public void show() {
  13. System.out.println("匿名内部类");
  14. }
  15. };
  16. /*
  17. 既然是对象,可直接在后面调用方法
  18. */
  19. new Inter(){
  20. @Override
  21. public void show() {
  22. System.out.println("匿名内部类");
  23. }
  24. }.show();
  25. /*
  26. 可看做Inter接口的实现类对象
  27. */
  28. Inter i = new Inter(){
  29. @Override
  30. public void show() {
  31. System.out.println("匿名内部类");
  32. }
  33. };
  34. i.show();
  35. }
  36. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. /*
  4. Outer.Inner oi = new Outer().new Inner();
  5. oi.show();
  6. */
  7. Outer o = new Outer();
  8. o.method();
  9. }
  10. }

匿名内部类
匿名内部类

使用

  1. public interface Jumpping {
  2. void jump();
  3. }
  1. public class JumppingOperator {
  2. public void method(Jumpping j){
  3. j.jump();
  4. }
  5. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. JumppingOperator jo = new JumppingOperator();
  4. /*
  5. 匿名函数作接口的实现类对象,以匿名函数作参数传入method方法
  6. */
  7. jo.method(new Jumpping() {
  8. @Override
  9. public void jump() {
  10. System.out.println("匿名函数1号");
  11. }
  12. });
  13. jo.method(new Jumpping() {
  14. @Override
  15. public void jump() {
  16. System.out.println("匿名函数2号");
  17. }
  18. });
  19. }
  20. }

Math类函数

  1. public static void main(String[] args) {
  2. //取绝对值
  3. System.out.println(Math.abs(-88.2));
  4. //向上取整,返回类型为float
  5. System.out.println(Math.ceil(12.49));
  6. System.out.println(Math.ceil(12.56));
  7. //向下取整,返回类型为float
  8. System.out.println(Math.floor(12.49));
  9. System.out.println(Math.floor(12.56));
  10. //四舍五入取整,返回int类型
  11. System.out.println(Math.round(12.49F));
  12. System.out.println(Math.round(12.56F));
  13. //返回两数最大最小
  14. System.out.println(Math.max(12,43));
  15. System.out.println(Math.min(12,43));
  16. //返回a的b次方,即2的3次方,类型为float型 8.0
  17. System.out.println(Math.pow(2,3));
  18. //返回[0,1)之间的随机数
  19. System.out.println(Math.random());
  20. }

System类

  1. public static void main(String[] args) {
  2. System.out.println("开始");
  3. System.exit(0); //结束java虚拟机运行,将不会往后执行
  4. System.out.println("结束");
  5. /*
  6. 返回1970年1月1日至今(系统时间)的毫秒数
  7. */
  8. double l = System.currentTimeMillis()*1.0/1000/60/60/24/365;
  9. System.out.println("1970年1月1日至今已有"+l+"年");
  10. /*
  11. 测试循环一万次打印所花费时间
  12. */
  13. long start = System.currentTimeMillis();
  14. for (int i=0;i<10000;i++){
  15. System.out.println(i);
  16. }
  17. long end = System.currentTimeMillis();
  18. System.out.println("循环一万次打印所花费"+(end-start)+"毫秒");
  19. }

Object类

  1. public class Student {
  2. private String name;
  3. private int age;
  4. public Student(String name, int age) {
  5. this.name = name;
  6. this.age = age;
  7. }
  8. public String getName() {
  9. return name;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. public int getAge() {
  15. return age;
  16. }
  17. public void setAge(int age) {
  18. this.age = age;
  19. }
  20. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Student s = new Student("张三",18);
  4. System.out.println(s);
  5. //fit.itheima_03.Student@1b6d3586
  6. Student s1 = new Student("张三",18);
  7. //都比较的是地址值
  8. System.out.println(s==s1); //false
  9. System.out.println(s.equals(s1)); //false
  10. }
  11. }

重写toString方法后

  1. @Override
  2. public String toString() {
  3. return "Student{" +
  4. "name='" + name + '\'' +
  5. ", age=" + age +
  6. '}';
  7. }
  1. Student s = new Student("张三",18);
  2. System.out.println(s);
  3. //Student{name='张三', age=18}

重写equals方法,Alt+insert, IDEA default

  1. @Override
  2. public boolean equals(Object o) {
  3. /*
  4. this---->s
  5. o---->s1
  6. */
  7. //比较地址
  8. if (this == o) return true;
  9. //判断是否同类
  10. if (o == null || getClass() != o.getClass()) return false;
  11. //向下转型
  12. Student student = (Student) o;
  13. //比较age
  14. if (age != student.age) return false;
  15. //再比较name
  16. return name != null ? name.equals(student.name) : student.name == null;
  17. }
  18. @Override
  19. public int hashCode() {
  20. int result = name != null ? name.hashCode() : 0;
  21. result = 31 * result + age;
  22. return result;
  23. }
  1. public static void main(String[] args) {
  2. Student s = new Student("张三",18);
  3. Student s1 = new Student("张三",18);
  4. //重写后的equals将比较的是内容
  5. System.out.println(s==s1); //false
  6. System.out.println(s.equals(s1)); //true
  7. }

Arrays类

  1. public static void main(String[] args) {
  2. int[] arr = {43,21,43,6,3,67,87,54};
  3. System.out.println(arr);
  4. // [I@1b6d3586
  5. System.out.println(Arrays.toString(arr));
  6. // [43, 21, 43, 6, 3, 67, 87, 54]
  7. Arrays.sort(arr); //排序
  8. System.out.println(Arrays.toString(arr));
  9. // [3, 6, 21, 43, 43, 54, 67, 87]
  10. }

工具类设计思想

构造方法用private修饰 , 防止外界创建对象

成员方法使用 public static修饰,可直接使用类名访问方法

包装类

java基础 - 图4

Int与String相互转换

  1. public static void main(String[] args) {
  2. int num = 100;
  3. System.out.println(getType(num)+"---"+num);
  4. //class java.lang.Integer---100
  5. String s1 = ""+num;
  6. System.out.println(getType(s1)+"---"+s1);
  7. //class java.lang.String---100
  8. String s2 = String.valueOf(num);
  9. System.out.println(getType(s2)+"---"+s2);
  10. //class java.lang.String---100
  11. String s = "100";
  12. Integer i = Integer.valueOf(s);
  13. System.out.println(getType(i)+"---"+i);
  14. //class java.lang.Integer---100
  15. int x = i.intValue();
  16. System.out.println(getType(x)+"---"+x);
  17. //class java.lang.Integer---100
  18. int y = Integer.parseInt(s);
  19. System.out.println(getType(y)+"---"+y);
  20. //class java.lang.Integer---100
  21. }
  22. private static String getType(Object a) {
  23. return a.getClass().toString();
  24. }

常用方法

Int ——> String

String s2 = String.valueOf(num);

String——> Int

int y = Integer.parseInt(s);

集合与数组转换

  1. public static void main(String[] args) {
  2. String str = "23 98 54 76 12 87";
  3. //分割转为String[]数组
  4. String[] strarr = str.split(" ");
  5. Arrays.sort(strarr);
  6. System.out.println(Arrays.toString(strarr));
  7. /*
  8. //转换为集合
  9. ArrayList<Integer> ints = new ArrayList<>();
  10. for (String s : strarr) {
  11. int y = Integer.parseInt(s);
  12. ints.add(y);
  13. }
  14. System.out.println(ints);
  15. //转换为Integer[]数组,排序
  16. Integer[] arr = new Integer[strarr.length];
  17. ints.toArray(arr);
  18. Arrays.sort(arr);
  19. System.out.println(Arrays.toString(arr));
  20. */
  21. //转为字符串
  22. StringBuilder sb = new StringBuilder();
  23. for (String a:strarr){
  24. sb.append(a).append(" ");
  25. }
  26. System.out.println(sb);
  27. }
  1. 【强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一样的数组,大小就是 list.size()
    说明: 使用 toArray 带参方法,入参分配的数组空间不够大时,toArray 方法内部将重新分配内存空间,并返回新数组地址;如果数组元素大于实际所需,下标为[ list.size() ]的数组元素将被置为 null,其它数组元素保持原值,因此最好将方法入参数组大小定义与集合元素个数一致。
    正例:
    反例: 直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出现 ClassCastException 错误。

    1. List<String> list = new ArrayList<String>(2);
    2. list.add("guan");
    3. list.add("bao");
    4. String[] array = new String[list.size()];
    5. array = list.toArray(array);
  2. 【强制】使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方
    法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
    说明: asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList 体现的是适配器模式,只是转换接口,后台的数据仍是数组。
    第一种情况:list.add("c"); 运行时异常。
    第二种情况:str[0] = "gujin"; 那么 list.get(0)也会随之修改。

    1. String[] str = new String[] { "a", "b" };
    2. List list = Arrays.asList(str);

装箱与拆箱

  1. //装箱
  2. Integer i = Integer.valueOf(100);
  3. //自动装箱
  4. Integer i1 = 100;
  5. //拆箱
  6. int in = i1.intValue();
  7. //自动拆箱
  8. int in1 = i1;

Date

  1. Date date = new Date();
  2. System.out.println(date);
  3. //Sun Nov 07 18:26:44 CST 2021
  4. System.out.println(date.getTime());
  5. //返回1970年1月1日到目前的毫秒数
  6. //1636280997605
  7. long time = System.currentTimeMillis();
  8. //返回1970年1月1日到目前的毫秒数
  9. System.out.println(time);
  10. //1636281155593

SimpleDateFormat

  1. public static void main(String[] args) throws ParseException {
  2. //Date转String
  3. Date date = new Date();
  4. SimpleDateFormat sdf = new SimpleDateFormat();
  5. String s = sdf.format(date);
  6. System.out.println(s);
  7. //21-11-7 下午7:33
  8. SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 ");
  9. String s1 = sdf1.format(date);
  10. System.out.println(s1);
  11. //2021年11月07日 19时33分03秒
  12. //String到date
  13. String ss = "2021-11-06 23:13:33";
  14. SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  15. Date dd = sdf2.parse(ss);
  16. System.out.println(dd);
  17. //Sat Nov 06 23:13:33 CST 2021
  18. }

封装为工具类

  1. public class DateUtils {
  2. //私有工具类
  3. private DateUtils(){}
  4. public static String dateToString(Date date,String format){
  5. SimpleDateFormat sdf = new SimpleDateFormat(format);
  6. String dateString = sdf.format(date);
  7. return dateString;
  8. }
  9. public static Date stringToDate(String dateString,String format) throws ParseException {
  10. SimpleDateFormat sdf = new SimpleDateFormat(format);
  11. Date date1 = sdf.parse(dateString);
  12. return date1;
  13. }
  14. }

测试

  1. public static void main(String[] args) throws ParseException {
  2. Date date = new Date();
  3. String s = DateUtils.dateToString(date, "yyyy年MM月dd日 HH时mm分ss秒");
  4. System.out.println(s);
  5. //2021年11月07日 19时54分30秒
  6. String s1 = "2021-11-07 12:12:12";
  7. Date date1 = DateUtils.stringToDate(s1,"yyyy-MM-dd HH:mm:ss");
  8. System.out.println(date1);
  9. //Sun Nov 07 12:12:12 CST 2021
  10. }

Calendar

  1. // 获取 日历类对象
  2. Calendar c = Calendar.getInstance();
  3. //System.out.println(c);
  4. int year = c.get(Calendar.YEAR);
  5. int month = c.get(Calendar.MONTH)+1;
  6. int date = c.get(Calendar.DATE);
  7. System.out.println(year+"年"+month+"月"+date+"日");
  8. //2021年11月7日
  9. c.add(Calendar.YEAR,-1); //一年前
  10. int year1 = c.get(Calendar.YEAR);
  11. int month1 = c.get(Calendar.MONTH)+1;
  12. int date1 = c.get(Calendar.DATE);
  13. System.out.println(year1+"年"+month1+"月"+date1+"日");
  14. //2020年11月7日
  1. // 获取 日历类对象
  2. Calendar c = Calendar.getInstance();
  3. //System.out.println(c);
  4. //设定 日历,注意月份从0开始
  5. c.set(2021,11,8);
  6. int year = c.get(Calendar.YEAR);
  7. int month = c.get(Calendar.MONTH)+1;
  8. int date = c.get(Calendar.DATE);
  9. System.out.println(year+"年"+month+"月"+date+"日");
  10. //2021年12月8日

异常

图片.png

异常处理

JVM默认处理方式
1.打印出错信息(原因及出错位置)
2.停止执行

  1. public static void main(String[] args) throws ParseException {
  2. System.out.println("开始");
  3. method();
  4. System.out.println("结束");
  5. }
  6. public static void method(){
  7. try {
  8. int[] arr = {1,2,3};
  9. System.out.println(arr[3]);
  10. }catch (ArrayIndexOutOfBoundsException e){
  11. e.printStackTrace(); //输出错误信息到控制台
  12. System.out.println("数组索引不存在");
  13. }
  14. }

开始 数组索引不存在 结束 java.lang.ArrayIndexOutOfBoundsException: 3 at fit.itheima_05.Demo.method(Demo.java:17) at fit.itheima_05.Demo.main(Demo.java:10)

Process finished with exit code 0

  1. e.printStackTrace(); //输出错误信息到控制台
  2. System.out.println("数组索引不存在");
  3. System.out.println(e.getMessage()); //输出错误原因
  4. //3
  5. System.out.println(e.toString());
  6. //java.lang.ArrayIndexOutOfBoundsException: 3
  • 编译时异常—必须显示处理,否则程序不能运行—-父类为Exception
  • 运行时异常—无需显示处理,但也可—-父类为RuntimeException

异常处理 — throws 类名

编译时异常,不处理将无法运行
throws 类名 抛出异常 , 谁调用,谁处理
只是抛出,并没有真正处理

  1. public static Date stringToDate(String dateString,String format) throws ParseException {
  2. SimpleDateFormat sdf = new SimpleDateFormat(format);
  3. Date date1 = sdf.parse(dateString);
  4. //parse方法提示,我可能会出错,必须抛出错误.
  5. //添加 throws ParseException 抛出异常
  6. return date1;
  7. }

自定义异常

extends Exception

  1. /*
  2. 自定义异常类
  3. */
  4. public class ScoreException extends Exception {
  5. public ScoreException() {
  6. }
  7. public ScoreException(String message) {
  8. super(message);
  9. }
  10. }
  1. public class Teacher {
  2. public void checkScore(int score) throws ScoreException {
  3. if (score< 0||score>100){
  4. throw new ScoreException("你的分数超出范围");
  5. }else{
  6. System.out.println("分数正常");
  7. }
  8. }
  9. }
  1. public class Demo {
  2. public static void main(String[] args) {
  3. Scanner scanner = new Scanner(System.in);
  4. System.out.println("请输入:");
  5. int score = scanner.nextInt();
  6. Teacher teacher = new Teacher();
  7. try {
  8. teacher.checkScore(score);
  9. } catch (ScoreException scoreException) {
  10. scoreException.printStackTrace();
  11. }
  12. }
  13. }

请输入: 120 fit.itheima_05.DateUtils: 你的分数超出范围 at fit.itheima_05.Teacher.checkScore(Teacher.java:6) at fit.itheima_05.Demo.main(Demo.java:15)

Process finished with exit code 0

Collection 集合

image.png

  1. public static void main(String[] args) {
  2. Collection<String> c = new ArrayList<String>();
  3. c.add("hello");
  4. c.add("java");
  5. System.out.println(c);
  6. //重写了toString
  7. //输出 [hello, java]
  8. }

image.png

快捷键 ——Alt+7 展示类结构

  1. public static void main(String[] args) {
  2. Collection<String> c = new ArrayList<String>();
  3. //添加元素
  4. c.add("hello");
  5. c.add("java");
  6. //移除元素
  7. System.out.println(c.remove("hello"));
  8. //判断元素是否存在
  9. System.out.println(c.contains("hello"));
  10. //判断集合是否为空
  11. System.out.println(c.isEmpty());
  12. //获取集合长度
  13. System.out.println(c.size());
  14. System.out.println(c);
  15. }

遍历

  1. public static void main(String[] args) {
  2. Collection<String> c = new ArrayList<String>();
  3. //添加元素
  4. c.add("hello");
  5. c.add("java");
  6. c.add("你好");
  7. //创建迭代对象
  8. Iterator<String> it = c.iterator();
  9. //判断对象是否存在
  10. while (it.hasNext()){
  11. //输出
  12. System.out.println(it.next());
  13. }
  14. System.out.println(c);
  15. }

List 有序集合 -序列-允许重复

  1. public static void main(String[] args) {
  2. List<String> list = new ArrayList<>();
  3. list.add("hello");
  4. list.add("java");
  5. list.add("world");
  6. System.out.println(list);
  7. Iterator<String> it = list.iterator();
  8. while (it.hasNext()){
  9. System.out.println(it.next());
  10. }
  11. /*
  12. List 特有方法,注意索引越界问题
  13. */
  14. //指定位置添加元素
  15. list.add(1,"JavaEE");
  16. System.out.println(list);
  17. //删除指定索引元素,并返回被删除的元素
  18. System.out.println(list.remove(1));
  19. System.out.println(list);
  20. //修改指定索引处元素
  21. System.out.println(list.set(1,"JavaWeb"));
  22. System.out.println(list);
  23. //获取指定索引元素
  24. System.out.println(list.get(1));
  25. //遍历
  26. for (int i = 0;i<list.size();i++){
  27. System.out.println(list.get(i));
  28. }
  29. }

并发修改异常

  1. public static void main(String[] args) {
  2. List<String> list = new ArrayList<>();
  3. list.add("hello");
  4. list.add("java");
  5. list.add("world");
  6. Iterator<String> it = list.iterator();
  7. while (it.hasNext()){
  8. String s = it.next();
  9. if (s.equals("world")){
  10. list.add("javaEE");
  11. }
  12. }
  13. }

Exception in thread “main” java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909) at java.util.ArrayList$Itr.next(ArrayList.java:859) at fit.itheima_05.Demo.main(Demo.java:14)

Process finished with exit code 1

迭代器 判断作 预期修改值与实际修改值 不同导致
解决:使用for循环遍历

  1. public static void main(String[] args) {
  2. List<String> list = new ArrayList<>();
  3. list.add("hello");
  4. list.add("java");
  5. list.add("world");
  6. for(int i = 0;i<list.size();i++){
  7. String s = list.get(i);
  8. if (s.equals("world")){
  9. list.add("javaEE");
  10. }
  11. }
  12. System.out.println(list);
  13. //[hello, java, world, javaEE]
  14. }

列表迭代器

任意方向开始遍历
image.png
sli.add(“javaEE”); 使用 listIterator 对象的add方法,将不会报错

  1. public static void main(String[] args) {
  2. List<String> list = new ArrayList<>();
  3. list.add("hello");
  4. list.add("java");
  5. list.add("world");
  6. ListIterator<String> sli = list.listIterator();
  7. while (sli.hasNext()){
  8. String s = sli.next();
  9. if (s.equals("world")){
  10. sli.add("javaEE");
  11. }
  12. }
  13. System.out.println(list);
  14. }

增强for循环

原理:
底层包装了 迭代器,
所以也会报 并发修改异常

  1. public static void main(String[] args) {
  2. List<String> list = new ArrayList<>();
  3. list.add("hello");
  4. list.add("java");
  5. list.add("world");
  6. for (String ss:list){
  7. if (ss.equals("world")){
  8. list.add("javaEE");
  9. }
  10. }
  11. System.out.println(list);
  12. }

Exception in thread “main” java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909) at java.util.ArrayList$Itr.next(ArrayList.java:859) at fit.itheima_05.Demo.main(Demo.java:21)

Process finished with exit code 1

数据结构

  • 栈 —- 先进后出
  • 队列 —- 先进先出
  • 数组—-查询快,增删慢
  • 链表 —- 查询慢,增删快(对比数组)

//List 子类集合特点
/
ArrayList 底层为数组
LinkedList 底层为链表
/

  1. public static void main(String[] args) {
  2. //List 子类集合特点
  3. /*
  4. ArrayList 底层为数组
  5. LinkedList 底层为链表
  6. */
  7. List<String> list = new LinkedList<>();
  8. list.add("hello");
  9. list.add("java");
  10. list.add("world");
  11. for (String ss : list) {
  12. System.out.println(ss);
  13. }
  14. System.out.println("-------------");
  15. for (int i = 0; i < list.size(); i++) {
  16. System.out.println(list.get(i));
  17. }
  18. System.out.println("-------------");
  19. Iterator<String> it = list.iterator();
  20. while (it.hasNext()) {
  21. System.out.println(it.next());
  22. }
  23. System.out.println("-------------");
  24. ListIterator<String> lit = list.listIterator();
  25. while (lit.hasNext()) {
  26. System.out.println(lit.next());
  27. }
  28. }

hello java

world

hello java

world

hello java

world

hello java world

Process finished with exit code 0

linkedlist

  1. public static void main(String[] args) {
  2. //List 子类集合特点
  3. /*
  4. ArrayList 底层为数组
  5. LinkedList 底层为链表
  6. */
  7. LinkedList<String> list = new LinkedList<>();
  8. list.add("hello");
  9. list.add("java");
  10. list.add("world");
  11. /*
  12. LinkedList 特有方法
  13. */
  14. //在开头添加元素
  15. list.addFirst("javaWEB");
  16. //在末位添加元素,注意add也是在末位添加元素
  17. list.addLast("JavaEE");
  18. System.out.println(list);
  19. //[javaWEB, hello, java, world, JavaEE]
  20. //删除首位元素
  21. System.out.println(list.removeFirst());
  22. //javaWEB
  23. //删除末位元素
  24. System.out.println(list.removeLast());
  25. //JavaEE
  26. System.out.println(list);
  27. //[hello, java, world]
  28. }

Set集合

HashSet:对迭代集合的顺序不作保证,可能会乱

  1. /*
  2. Set集合:
  3. 不包含重复元素
  4. 不带索引
  5. */
  6. //HashSet:对迭代集合的顺序不作保证,可能会乱
  7. public static void main(String[] args) {
  8. Set<String> set = new HashSet<>();
  9. set.add("hello");
  10. set.add("java");
  11. set.add("world");
  12. System.out.println(set);
  13. //[java, world, hello]
  14. set.add("world");
  15. System.out.println(set);
  16. //[java, world, hello]
  17. }

哈希值

  1. /*
  2. 哈希值:是JDK根据对象地址或字符串或数字
  3. 计算出的int类型的数字
  4. hashCode :返回对象的哈希码值
  5. */
  6. public static void main(String[] args) {
  7. String s = new String("msd");
  8. String s1 = new String("aaa");
  9. System.out.println(s.hashCode());
  10. //108414
  11. System.out.println(s1.hashCode());
  12. //96321
  13. //默认情况下,不同对象的哈希值不同
  14. //重写hashCode方法可使不同对象的哈希值相同
  15. System.out.println("hello".hashCode());
  16. System.out.println("hello".hashCode());
  17. System.out.println("java".hashCode());
  18. //可能相同
  19. System.out.println("重地".hashCode()); //1179395
  20. System.out.println("通话".hashCode()); //1179395
  21. }

image.png

image.png

  1. /*
  2. 数据结构-->哈希表
  3. */
  4. public static void main(String[] args) {
  5. //对哈希值 进行16取余
  6. //先对比哈希值,再对比内容
  7. HashSet<Teacher> set = new HashSet<>();
  8. Teacher s1 = new Teacher("张三", 12);
  9. Teacher s2 = new Teacher("李四", 13);
  10. Teacher s3 = new Teacher("王五", 12);
  11. Teacher s4 = new Teacher("李四", 13);
  12. set.add(s1);
  13. set.add(s2);
  14. set.add(s3);
  15. set.add(s4);
  16. System.out.println(set);
  17. //[Teacher{name='王五', age=12}, Teacher{name='李四', age=13}, Teacher{name='张三', age=12}, Teacher{name='李四', age=13}]
  18. /*
  19. 发现重复的元素也被添加进来了,是因为没有重写equals方法和hashCode
  20. 在teacher类中 重写后
  21. //[Teacher{name='王五', age=12}, Teacher{name='张三', age=12}, Teacher{name='李四', age=13}]
  22. */
  23. }

image.png

LinkedHashSet

  1. /*
  2. LinkedHashSet-->底层结构:链表和哈希表
  3. 由链表保证 顺序 有序
  4. 由哈希表 保证 元素唯一
  5. */
  6. public static void main(String[] args) {
  7. LinkedHashSet<String> ss = new LinkedHashSet<>();
  8. ss.add("hello");
  9. ss.add("java");
  10. ss.add("world");
  11. System.out.println(ss);
  12. //[hello, java, world]
  13. ss.add("world");
  14. System.out.println(ss);
  15. //[hello, java, world]
  16. }

TreeSet 集合

image.png

  1. /*
  2. TreeSet -->不重复
  3. 自然有序
  4. */
  5. public static void main(String[] args) {
  6. //需使用基本数据类型对应的包装类型
  7. TreeSet<Integer> it = new TreeSet<>();
  8. it.add(20);
  9. it.add(10);
  10. it.add(40);
  11. it.add(30);
  12. it.add(50);
  13. System.out.println(it);
  14. //[10, 20, 30, 40, 50]
  15. it.add(50);
  16. System.out.println(it);
  17. //[10, 20, 30, 40, 50]
  18. }

自然排序 Comparable

  1. public class Teacher implements Comparable<Teacher> {
  2. private String name;
  3. private int age;
  4. public Teacher() {
  5. }
  6. public Teacher(String name, int age) {
  7. this.name = name;
  8. this.age = age;
  9. }
  10. @Override
  11. public String toString() {
  12. return "Teacher{" +
  13. "name='" + name + '\'' +
  14. ", age=" + age +
  15. '}';
  16. }
  17. @Override
  18. public boolean equals(Object o) {
  19. if (this == o) return true;
  20. if (o == null || getClass() != o.getClass()) return false;
  21. Teacher teacher = (Teacher) o;
  22. if (age != teacher.age) return false;
  23. return name != null ? name.equals(teacher.name) : teacher.name == null;
  24. }
  25. @Override
  26. public int hashCode() {
  27. int result = name != null ? name.hashCode() : 0;
  28. result = 31 * result + age;
  29. return result;
  30. }
  31. public String getName() {
  32. return name;
  33. }
  34. public void setName(String name) {
  35. this.name = name;
  36. }
  37. public int getAge() {
  38. return age;
  39. }
  40. public void setAge(int age) {
  41. this.age = age;
  42. }
  43. @Override
  44. public int compareTo(Teacher o) {
  45. int num = this.age - o.age; //age升序
  46. //int num = o.age - this.age; //age降序
  47. //如年龄相同,比较名字
  48. int num2 = num == 0?this.name.compareTo(o.name):num;
  49. return num2;
  50. }
  51. }
  1. /*
  2. TreeSet -->不重复
  3. 自然有序
  4. */
  5. public static void main(String[] args) {
  6. TreeSet<Teacher> set = new TreeSet<>();
  7. Teacher s1 = new Teacher("张三", 40);
  8. Teacher s2 = new Teacher("李四", 30);
  9. Teacher s3 = new Teacher("王五", 10);
  10. Teacher s4 = new Teacher("李四", 20);
  11. //Teacher s5 = new Teacher("m四", 20);
  12. set.add(s1);
  13. set.add(s2);
  14. set.add(s3);
  15. set.add(s4);
  16. //set.add(s5);
  17. for (Teacher t:set){
  18. System.out.println(t.getName()+","+t.getAge());
  19. }
  20. /*
  21. Exception in thread "main" java.lang.ClassCastException: fit.itheima_05.Teacher cannot be cast to java.lang.Comparable
  22. at java.util.TreeMap.compare(TreeMap.java:1294)
  23. at java.util.TreeMap.put(TreeMap.java:538)
  24. at java.util.TreeSet.add(TreeSet.java:255)
  25. at fit.itheima_05.Demo.main(Demo.java:18)
  26. Process finished with exit code 1
  27. */
  28. //teacher类 实现Comparable接口,重写compareTo方法,根据其返回值输出
  29. //return 0; --> [Teacher{name='张三', age=40}]
  30. //return 1; -->
  31. /*
  32. 张三,40
  33. 李四,30
  34. 王五,10
  35. 李四,20
  36. */
  37. //return -1; -->
  38. /*
  39. 李四,20
  40. 王五,10
  41. 李四,30
  42. 张三,40
  43. */
  44. //return (this.age - o.age);
  45. /*
  46. 王五,10
  47. 李四,20
  48. 李四,30
  49. 张三,40
  50. */
  51. }

image.png

比较器Comparator 排序

image.png

  1. public static void main(String[] args) {
  2. //创建内部类
  3. TreeSet<Teacher> ts = new TreeSet<>(new Comparator<Teacher>() {
  4. @Override
  5. public int compare(Teacher o1, Teacher o2) {
  6. int num = o1.getAge() - o2.getAge();
  7. int num2 = num == 0?o1.getName().compareTo(o2.getName()):num;
  8. return num;
  9. }
  10. });
  11. Teacher s1 = new Teacher("张三", 40);
  12. Teacher s2 = new Teacher("李四", 30);
  13. Teacher s3 = new Teacher("王五", 10);
  14. Teacher s4 = new Teacher("李四", 20);
  15. //Teacher s5 = new Teacher("m四", 20);
  16. ts.add(s1);
  17. ts.add(s2);
  18. ts.add(s3);
  19. ts.add(s4);
  20. //set.add(s5);
  21. for (Teacher t:ts){
  22. System.out.println(t.getName()+","+t.getAge());
  23. }

成绩排序输出

泛型

image.png

  1. public static void main(String[] args) {
  2. //不指定存储类型
  3. Collection c = new ArrayList();
  4. c.add("hello");
  5. c.add("java");
  6. c.add("world");
  7. c.add(100);
  8. Iterator it = c.iterator();
  9. while (it.hasNext()) {
  10. String s = (String) it.next();
  11. System.out.println(s);
  12. }
  13. /*
  14. hello
  15. java
  16. world
  17. Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  18. at fit.itheima_05.Test.main(Test.java:16)
  19. Process finished with exit code 1
  20. */
  21. }

使用泛型
1.避免强制类型转换
2.提前到运行时异常

  1. public static void main(String[] args) {
  2. //指定String存储类型
  3. Collection<String> c = new ArrayList();
  4. c.add("hello");
  5. c.add("java");
  6. c.add("world");
  7. //c.add(100);
  8. Iterator<String> it = c.iterator();
  9. while (it.hasNext()) {
  10. System.out.println(it.next());
  11. }
  12. /*
  13. hello
  14. java
  15. world
  16. */
  17. }

image.png

  1. /*
  2. 泛型类
  3. */
  4. public class Generic<T> {
  5. private T t;
  6. public T getT() {
  7. return t;
  8. }
  9. public void setT(T t) {
  10. this.t = t;
  11. }
  12. }
  1. public static void main(String[] args) {
  2. Teacher t = new Teacher();
  3. t.setAge(30);
  4. System.out.println(t.getAge());
  5. // t.setAge("string类型"); //报错
  6. // System.out.println(t.getAge());
  7. Generic<String> sg = new Generic<>();
  8. sg.setT("String类型");
  9. System.out.println(sg.getT());
  10. Generic<Integer> ig = new Generic<>();
  11. ig.setT(100);
  12. System.out.println(ig.getT());
  13. }
  1. /*
  2. 泛型类
  3. */
  4. public class Generic<T> {
  5. public void show(T t) {
  6. System.out.println(t);
  7. }
  8. }
  1. public static void main(String[] args) {
  2. Generic g = new Generic<>();
  3. //调用不同类型的数据
  4. g.show("String");
  5. g.show(100);
  6. g.show(true);
  7. g.show(12.56);
  8. }

泛型方法

  1. public class Generic {
  2. /*
  3. 泛型方法
  4. */
  5. public <T> void show(T t) {
  6. System.out.println(t);
  7. }
  8. }
  1. public static void main(String[] args) {
  2. Generic g = new Generic();
  3. //调用不同类型的数据
  4. g.show("String");
  5. g.show(100);
  6. g.show(true);
  7. g.show(12.56);
  8. }

泛型接口

  1. /*
  2. 泛型接口
  3. */
  4. public interface Generic<T> {
  5. void show(T t);
  6. }
  1. /*
  2. 泛型接口实现类
  3. */
  4. public class GenericImpl<T> implements Generic<T> {
  5. @Override
  6. public void show(T t) {
  7. System.out.println(t);
  8. }
  9. }
  1. public static void main(String[] args) {
  2. Generic g = new GenericImpl();
  3. //调用不同类型的数据
  4. g.show("String");
  5. g.show(100);
  6. g.show(true);
  7. g.show(12.56);
  8. }

类型通配符

image.png

  1. /*
  2. Object-->Number-->Integer
  3. */
  4. public static void main(String[] args) {
  5. //? 通配所有类型
  6. List<?> list1 = new ArrayList<Object>();
  7. List<?> list2 = new ArrayList<Number>();
  8. List<?> list3 = new ArrayList<Integer>();
  9. //指定上限 : 最高父类只能到 NUmber,不能为Object
  10. List<? extends Number> list4 = new ArrayList<Object>(); //报错
  11. List<? extends Number> list5 = new ArrayList<Number>();
  12. List<? extends Number> list6 = new ArrayList<Integer>();
  13. //指定下限 : 最低子类为 Number,不能更低,即Integer
  14. List<? super Number> list7 = new ArrayList<Object>();
  15. List<? super Number> list8 = new ArrayList<Number>();
  16. List<? super Number> list9 = new ArrayList<Integer>(); //报错
  17. }

可变参数

定义: public static int sum(int… a)
如 一个方法既包含可变参数,有包含普通参数,
可变参数 必须 放在最后

  1. /*
  2. 可变参数
  3. */
  4. public static void main(String[] args) {
  5. System.out.println(sum(1,2));
  6. System.out.println(sum(1,2,3));
  7. System.out.println(sum(1,2,3,4));
  8. }
  9. public static int sum(int... a){
  10. //a 为一个数组[1, 2, 3, 4]
  11. System.out.println(Arrays.toString(a));
  12. int sum = 0;
  13. for (int i :a){
  14. sum+=i;
  15. }
  16. return sum;
  17. }

image.png

  1. public static void main(String[] args) {
  2. List<String> list = Arrays.asList("hello", "java", "world");
  3. //不支持添加和删除
  4. // list.add("web");
  5. // list.remove("world");
  6. //java.lang.UnsupportedOperationException
  7. //但是支持修改
  8. list.set(1, "WEB");
  9. System.out.println(list);
  10. }
  1. public static void main(String[] args) {
  2. //List.of JDK9新特性,创建的集合不支持增删改
  3. List<String> list = List.of("hello", "java", "world");
  4. }
  1. public static void main(String[] args) {
  2. //Set.of JDK9新特性,创建的集合不支持增删,没有修改方法
  3. //创建时不能存入重复元素
  4. Set<String> set = Set.of("hello", "java", "world");
  5. }

Map 集合

image.png

  1. /*
  2. Map集合
  3. */
  4. public static void main(String[] args) {
  5. //创建Map对象
  6. Map<String, String> map = new HashMap<>();
  7. map.put("张三","34");
  8. map.put("李四","35");
  9. map.put("王五","36");
  10. System.out.println(map);
  11. //{李四=35, 张三=34, 王五=36}
  12. //当键重复,会覆盖之前的值
  13. map.put("王五","99");
  14. System.out.println(map);
  15. //{李四=35, 张三=34, 王五=99}
  16. }
  1. public static void main(String[] args) {
  2. //创建Map对象
  3. Map<String, String> map = new HashMap<>();
  4. map.put("张三","34");
  5. map.put("李四","35");
  6. map.put("王五","36");
  7. System.out.println(map);
  8. //{李四=35, 张三=34, 王五=36}
  9. System.out.println(map.remove("张三"));
  10. ////34
  11. System.out.println(map.remove("35"));
  12. //键不存在 --> null
  13. System.out.println(map);
  14. //{李四=35, 王五=36}
  15. //判断 键是否存在 -->false
  16. System.out.println(map.containsKey("张三"));
  17. //判断 值是否存在 -->true
  18. System.out.println(map.containsValue("35"));
  19. //获取map集合长度 --> 2
  20. System.out.println(map.size());
  21. //清空集合
  22. map.clear();
  23. //判断集合是否为空 -->true
  24. System.out.println(map.isEmpty());
  25. }
  1. public static void main(String[] args) {
  2. //创建Map对象
  3. Map<String, String> map = new HashMap<>();
  4. map.put("张三","34");
  5. map.put("李四","35");
  6. map.put("王五","36");
  7. //根据键 获取值
  8. System.out.println(map.get("张三")); //34
  9. System.out.println(map.get("傻逼")); //null
  10. //获取键的集合
  11. Set<String> mapKey = map.keySet();
  12. System.out.println(mapKey); //[李四, 张三, 王五]
  13. //获取值的集合
  14. Collection<String> mapValue = map.values();
  15. System.out.println(mapValue); //[35, 34, 36]
  16. }

遍历
Set> entrySet = map.entrySet(); 获取键值对集合

  1. public static void main(String[] args) {
  2. //创建Map对象
  3. Map<String, String> map = new HashMap<>();
  4. map.put("张三","34");
  5. map.put("李四","35");
  6. map.put("王五","36");
  7. //遍历输出
  8. for (String s :map.keySet()){
  9. System.out.println(s+","+map.get(s));
  10. }
  11. /*
  12. 李四,35
  13. 张三,34
  14. 王五,36
  15. */
  16. System.out.println("--------------");
  17. //获取键值对集合
  18. Set<Map.Entry<String, String>> entrySet = map.entrySet();
  19. for (Map.Entry<String, String> entry : entrySet) {
  20. System.out.println(entry);
  21. System.out.println(entry.getKey()+","+entry.getValue());
  22. }
  23. /*
  24. 李四=35
  25. 李四,35
  26. 张三=34
  27. 张三,34
  28. 王五=36
  29. 王五,36
  30. */
  31. }