• JAVA------基础篇


    java基础

    1.JDK

    JDK :java development kit
    JRE:java runtime environment
    JDK包含JRE
    java跨平台:因为java程序运行依赖虚拟机,虚拟机需要有对应操作系统的版本,而jre中有虚拟机。
    当你想要在Linux系统下运行,则需要安装对应的虚拟机,及对应的jdk版本,而对应的jdk版本中的jre有对应的虚拟机

    2.标识符:我们自己定义的名字

    类名:不能以数字开头,只能有_ $ 字母 数字
    类方法:前面小写,第二个单词大写。

    3.常量:不能变的值。system.out.println(100);

    4.变量:指在计算机内存中,可以随时改变的量。int i = 2; system.out.println(i);

    【注意:八个比特等于一个字节】

    5.算术运算符:int a=3; int b = a++ + 10;a=4,b=13

    6.数据类型:范围 byte

    7.方法:

    注意点:
    1.方法不能定义在另一个方法里面
    2.调用方法时,返回值是void,不能写在输出语句中
    3.方法重载:
    1.参数列表必须不同
    2.重载和参数变量名无关
    3.重载和返回值类型无关
    4.重载和修饰符无关
    总结:重载只看方法名和参数列表

    在这里插入图片描述

    当把方法中的void改为int并且加个返回值return ;则需要在main方法中调用change方法的同时需要给其赋值。如:a=change(a,b);否则还是会出现上面这种a,b不变的情况。

    在这里插入图片描述

    为什么这个方法跟上面差不多,只是把参数换了个引用类型参数,结果就能成功赋值?

    因为int[] arr = [1,2,3,4];在堆上开辟了一个容器,且有个地址返回给int[] arr,当你调用change,将arr[2]赋值为100,则方法会根据地址去对对应的arr[2]进行赋值,方法结束时,change退出方法栈,但是此时值以及改好。
    ArrayList<>:<>里面存放的是引用数据类型。如:int的引用数据类型是integer(四类八种中有两个基本数据类型和引用数据类型不同,一个是int(integer),一个是char(character))

    =============================================================

    transient:在不需要序列化的属性前面加个transient,则序列化对象的时候,这个属性就不会被序列化。

    序列化

    package com.li.demo01;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.Iterator;
    
    public class iterator {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            File file = new File("xxx.txt");
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream op = new ObjectOutputStream(fos);
            User user = new User(1,2);
            op.writeObject(user);
            op.flush();
            op.close();
    
            System.out.println(user);
    
            System.out.println("=========================================");
    
            FileInputStream fls = new FileInputStream(file);
            ObjectInputStream oi = new ObjectInputStream(fls);
            User user1 = (User) oi.readObject();
            System.out.println(user1);
    
        }
    }
    
    
    • 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
    实体类
    package com.li.demo01;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private static final long serialVersionUID = -134246534L;
        private int id;
        transient int age;
    
        public User() {
        }
    
        public User(int id, int age) {
            this.id = id;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", age=" + age +
                    '}';
        }
    }
    
    
    • 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

    输出结果

    User{id=1, age=2}
    =========================================
    User{id=1, age=0}
    
    进程已结束,退出代码 0
    
    • 1
    • 2
    • 3
    • 4
    • 5

    面向对象

    1.成员变量与局部变量的不同
    局部变量没有赋值不能输出,成员变量可以。
    
    public class demo7 {
    
    	static int x;
    	
    	public void run(){
    		int i;
    		System.out.println(i);//注意这里的i会报错,因为i为局部变量,局部变量没有赋值,是不能进行输出。
    	}
    	public static void main(String[] args) {
    		System.out.println(x);
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    内存位置不同

    在这里插入图片描述
    在这里插入图片描述

    生命周期不同
    成员变量,跟随对象,在堆中存储,内存等待JVM清理,生命周期较长
    局部变量,跟随方法,方法出栈,生命周期相对较短。

    注意:重点需要会掌握如何区分局部还是成员变量即可。

    面向对象方法参数:基本数据类型和引用数据类型
    基本数据类型

    在这里插入图片描述

    引用数据类型

    在这里插入图片描述

    private修饰词

    只能修饰成员变量,不能修饰局部变量
    总结:类中不需要对外提供的内容都私有化,包括属性的方法。
    以后再描述事物,属性都私有化,并提供setXXX getXXX方法对其进行访问。
    注意:私有仅仅是封装的体现形式而已。

    this关键字

    区分成员变量和局部变量的同名的情况
    方法中访问成员变量,写this.
    凡是写this. 的都是访问成员变量。

    在这里插入图片描述

    this的使用年纪的比较

    在这里插入图片描述

    extend继承

    在这里插入图片描述
    在这里插入图片描述

    当子父类中出现了同名成员变量时,在子类中若要访问父类中的成员变量,必须使用关键字super来完成。

    this. 调用自己本类成员

    super. 调用的自己的父类成员

    重写:子类和父类方法一样(参数名一样)的时候。(注意区别于重载,重载是参数不一样)

    子类重写父类的方法,保证子类方法的权限大于或者等于父类方法权限

    四大权限 public protected default private (方法默认是default权限)

    在这里插入图片描述
    在这里插入图片描述

    abstract

    在这里插入图片描述

    抽象类,不能实例化对象,不能new对象。

    不能创建对象的原因:如果你真的实例化对象了,对象.调用抽象方法,但是抽象方法中没有方法体,根本不能运行。
    抽象类强制它的子类执行抽象方法,重写父类的方法,就不需要写抽象修饰词,加上主体即可。

    在这里插入图片描述

    2.4抽象类的细节问题:

    1、抽象类一定是个父类?
    是的,因为不断抽取而来的。
    2、抽象类中是否可以不定义抽象方法。
    是可以的,那这个抽象类的存在到底有什么意义呢?不让该类创建对象,方法可以直接让子类去使用

    3、抽象关键字abstract不可以和哪些关键字共存?
    1、private:私有的方法子类是无法继承到的,也不存在覆盖,而abstract和private一起使用修饰方法,abstract既要子类去实现这个方法,而private修饰子类根本无法得到父类这个方法。互相矛盾。
    2、final,暂时不关注,后面学
    3、static,暂时不关注,后面学

    接口

    定义抽象方法:固定格式 public abstract 返回值类型 方法名字(参数列表);

    修饰符 public 写,或者不写都是public。但是别的地方不写则是default。
    接口中定义变量:固定格式:public static final 数据类型 变量名 = 值;(并且因为,static,所以它可以直接通过接口的名字直接调用它)我们不写前面这些修饰词,不代表没有,接口会自动写进去。

    如:

    在这里插入图片描述
    在这里插入图片描述

    注意点:接口和继承中当你实现接口,或者继承类时强制要求你写出方法是因为其中的abstract的原因。

    继承父类,当父类中方法有abstract,则继承时就需要重写。

    类对接口方法的实现的时候,不管接口中是否有写public abstract都需要加上public

    实现多个接口

    在这里插入图片描述

    实现多个接口需要避免这个情况

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    抽象类和接口的区别:

    抽象类是这个体系应该有的东西,而接口是体系中额外的扩展功能在这里插入图片描述

    interface 缉毒{
    	public abstract void 缉毒();
    }
    //定义犬科的这个提醒的共性功能
    abstract class 犬科{
    public abstract void 吃饭();
    public abstract void 吼叫();
    }
    // 缉毒犬属于犬科一种,让其继承犬科,获取的犬科的特性,
    //由于缉毒犬具有缉毒功能,那么它只要实现缉毒接口即可,这样即保证缉毒犬具备犬科的特性,也拥有了缉毒的功能
    class 缉毒犬 extends 犬科 implements 缉毒{
    
    	public void 缉毒() {
    	}
    	void 吃饭() {
    	}
    	void 吼叫() {
    	}
    }
    class 缉毒猪 implements 缉毒{
    	public void 缉毒() {
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    多态

    多态体现为父类引用变量可以指向子类对象。
    多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。
    在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

    如:接口 变量 = new 实现类():

    ********

    父类

    public class Animal {//父类
    	
    	static int cons = 1;
    	
    	int val = 1;
    	
    	final int fin = 1;
    	
    	public void eat() {
    		System.out.println("animal eat");
    	}
    	
    	
    	static void eat2() {
    		System.out.println("animal eat2");
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    子类

    public class Cat extends Animal{
    	
    	static int cons = 2;
    	
    	int val = 2;
    	
    	final int fin = 2;
    	
    	@Override
    	public void eat() {
    		System.out.println("cat eat");
    	}
    	
    	static void eat2() {
    		System.out.println("cat eat2");
    	}
    		
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    测试类(调用父子类中一样的方法,则输出结果是子类的方法,要想调用父类的方法,需要在父类中加上static。
    调用父子类中的成员,默认输出结果是父类的成员变量。原因【编译、运行都是跟着父类走】且通过多态调用的成员变量,无论是普通类型,静态类型,常量类型仍是父类的成员变量,因为成员变量不存在override(覆盖)问题

    public static void main(String[] args) {
    		Animal a = new Cat();//父类引用
    		
    		System.out.println(a.val);//成员变量
    		System.out.println(a.cons);//静态变量
    		System.out.println(a.fin);//常量
    		
    		a.eat();//成员方法
    		a.eat2();//静态方法
    		
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    输出结果

    1
    1
    1
    cat eat
    animal eat2
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    instanceof判断变量p是Student还是Teacher(前提:两个类都需要继承Person)。

    格式:引用变量 instanceof 类名

    boolean a = p instanceof Student;

    Person p = new Stduent();Person p = new Teacher();【Teacher 向上转型(优点:可以调用子类和父类的共有内容。缺点:不能调用子类中特有的内容。如何解决缺点:可以加强转。如:Teacher t = (Teacher)p;
    )】

    构造方法的作用:当我们new对象的时候自动赋值上去。以往都是new完对象再赋值。

    构造方法的定义格式

    权限 方法名(参数列表){
    }
    方法的名字,必须和类的名字完全一致
    构造方法不允许写返回值类型,void也不能写。

    当你new对象的时候,构造方法就执行,而且仅执行一次

    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210616092445352.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1Rocml2ZV9MQ1g=,size_16,co

    this在构造方法之间的调用:

    this():减轻了无参构造的代码量。
    package cn.itcast.demo03;
    /*
     *   this可以在构造方法之间进行调用
     *   this.的方式,区分局部变量和成员变量同名情况
     *   this在构造方法之间的调用,语法 this()
     */
    public class Person {
    	private String name;
    	private int age;
    	
    	public Person(){
    		//调用了有参数的构造方法
    		//参数李四,20传递给了变量name,age
    		this("李四",20);//调用this()需要让它再构造方法的第一行
    	}
    	/*
    	 *  构造方法,传递String,int
    	 *  在创建对象的同时为成员变量赋值
    	 */
    	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;
    	}
    	
    	
    }
    
    
    • 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
    package cn.itcast.demo03;
    
    public class Test {
    	public static void main(String[] args) {
    		//创建Person的对象,调用的是空参数的构造方法
    		//运行的结果 null 0
    		Person p = new Person();
    		
    		System.out.println(p.getName());
    		System.out.println(p.getAge());
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    内存图
    在这里插入图片描述

    super关键字

    父类
    在这里插入图片描述

    子类
    在这里插入图片描述
    测试类
    在这里插入图片描述

    在这里插入图片描述

    我们发现,当我们new一个子对象的时候,输出父类中无参构造的值。说明我们子类中有隐藏的

    public zi(){
    		super();
    	}
    
    • 1
    • 2
    • 3

    这段代码

    须知:子类中的构造方法是用来调用父类方法的。(super含义:标明了父类文件所在的内存区域)

    内存图
    在这里插入图片描述

    注意点:子类中所有的构造方法,无论重载多少个,第一行必须是super()

    如:
    父类

    /*
     *   手动写一个父类Person类的构造方法,加入int类型参数
     *   保存,子类就报错
     */
    public class Person {
    	public Person(int a){
    	
    	}
    	
    	public Person(double d){
    		
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    子类

    /*
     *  子类构造方法的报错原因: 找不到父类的空参数构造器
     *  子类中,没有手写构造,编译器添加默认的空参数
     *  public Student(){
     *     super();
     *  }
     *  编译成功,必须手动编写构造方法,请你在super中加入参数
     *  
     *  注意: 子类中所有的构造方法,无论重载多少个,第一行必须是super()
     *  如果父类有多个构造方法,子类任意调用一个就可以
     *  super()语句必须是构造方法第一行代码
     */
    public class Student extends Person{
    	public Student(){
    		
    		super(0.1);
    	
    	}
    	
    	public Student(String s){
    		super(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

    案例:
    父类

    public class Person extends Object{
    
    	public Person(int a) {
    	
    	}
    	
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    子类

    /*
     	构造方法第一行,写this()还是super()
     	不能同时存在,任选其一,保证子类的所有构造方法调用到父类的构造方法即可
     	
     	小结论: 无论如何,子类的所有构造方法,直接,间接必须调用到父类构造方法
     	子类的构造方法,什么都不写,默认的构造方法第一行 super();
     */
    public class Student extends Person{
    	public Student(){
    		//调用的是自己的构造方法
    		//间接形式调用到了父类的构造方法
    		this("abc");
    	}
    	
    	public Student(String s){
    		super(1);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    测试类

    public class Test {
    	public static void main(String[] args) {
    		new Student();
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    final修饰引用变量问题

    变量,保存内存地址,终身不变

    final Zi z2 = new Zi();
    z2 = new Zi();

    * final修饰成员变量

    • 成员变量,在堆内存,具有默认值
    • final修饰的成员变量,固定的不是内存的默认值
    • 固定的是,成员变量的手动赋值,绝对不是内存的默认
    • 成员变量的赋值,2种实现方式,一种是定义的时候,直接=赋值
    • 另一种赋值方式,采用构造方法赋值
    • 保证: 被final修饰的成员变量,只能被赋值一次
    • 成员变量,需要在创建对象前赋值,否则报错
    • 构造方法,是创建对象中的事情,可以为成员变量赋值
    • setXXX方法,创建对象之后的时候,不能为final修饰的成员赋值

    static

    在这里插入图片描述
    在这里插入图片描述

    静态不能写this,不能写super。因为this表示本类的对象引用,而静态优先于对象

    当我们的方法不是静态方法的时候,我们就需要去先new一个对象,才能调用那个方法。解决:那个方法为静态则可以不用new直接调用。在这里插入图片描述

    在这里插入图片描述

    内部类

    调用规则:内部类,可以使用外部类成员,包括私有外部类要使用内部类的成员,必须建立内部类对象。

    在这里插入图片描述
    在这里插入图片描述

    匿名内部类

    定义实现类,重写方法,创建实现类对象,一步搞定

    格式: new 接口或者父类(){

    重写抽象方法

    }

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    导包

    classpath是帮助虚拟机找到jar包的位置
    在命令窗口也可配置 如:set classpath=d:\method.jar
    在eclipse中直接在项目点击右键创建一个folder为lib,再把要导入的jar包放进去即可。

    String

    在这里插入图片描述

    Calendar

    /*
    	 *  闰年计算
    	 *  2000 3000
    	 *  高级的算法: 日历设置到指定年份的3月1日,add向前偏移1天,获取天数,29闰年
    	 */
    	public static void function_1(){
    		Calendar c = Calendar.getInstance();
    		//将日历,设置到指定年的3月1日
    		c.set(2088, 2, 1);
    		//日历add方法,向前偏移1天
    		c.add(Calendar.DAY_OF_MONTH, -1);
    		//get方法获取天数
    		int day = c.get(Calendar.DAY_OF_MONTH);
    		System.out.println(day);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    自动装拆箱

    /*
     *   JDK1.5后出现的特性,自动装箱和自动拆箱
     *   自动装箱: 基本数据类型,直接变成对象
     *   自动拆箱: 对象中的数据变回基本数据类型
     */
    public class IntegerDemo2 {
    	public static void main(String[] args) {
    		function_2();
    	}
    	/*
    	 *  关于自动装箱和拆箱一些题目
    	 */
    	public static void function_2(){
    		Integer i = new Integer(1);
    		Integer j = new Integer(1);
    		System.out.println(i==j);// false 对象地址
    		System.out.println(i.equals(j));// true  继承Object重写equals,比较的对象数据
    		
    		System.out.println("===================");
    		
    		Integer a = 500;
    		Integer b = 500;
    		System.out.println(a==b);//false
    		System.out.println(a.equals(b));//true
    		
    		System.out.println("===================");
    		
    		
    		//数据在byte范围内,JVM不会从新new对象
    		Integer aa = 127; // Integer aa = new Integer(127)
    		Integer bb = 127; // Integer bb = aa;
    		System.out.println(aa==bb); //true
    		System.out.println(aa.equals(bb));//true
    	}
    	
    	
    	//自动装箱和拆箱弊端,可能出现空指针异常
    	public static void function_1(){
    	    Integer in =null;	
    	    //in = null.intValue()+1
    	    in = in + 1;
    	    System.out.println(in);
    	}
    	
    	//自动装箱,拆箱的 好处: 基本类型和引用类直接运算
    	public static void function(){
    		//引用类型 , 引用变量一定指向对象
    		//自动装箱, 基本数据类型1, 直接变成了对象
    		
    		Integer in = 1; // Integer in = new Integer(1)
    		//in 是引用类型,不能和基本类型运算, 自动拆箱,引用类型in,转换基本类型
    		
    		//in+1  ==> in.inValue()+1 = 2    
    		// in = 2    自动装箱
    		in = in + 1;
    		
    		System.out.println(in);
    		
    	}
    }
    
    • 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

    集合

    java中三种长度表现形式

    数组. length 属性 返回值int

    字符串.length() 方法,返回值int

    集合.size()方法,返回值int

    public static void function(){
    		Collection coll = new ArrayList();
    		coll.add("abc");
    		coll.add("rtyg");
    		coll.add("43rt5yhju");
    
    		//注意要想获取String的长度,必须先向下转型
    		Iterator it = coll.iterator();
    		while(it.hasNext()){
    			String s = (String)it.next();
    			System.out.println(s.length());
    		}
    	}
    	//该转型存在安全隐患,如:当我们coll.add(1);增加整数时,由于jdk中的自动装箱特性,就会把整数转为Integer。此时下面的转型会报异常,因为Integer不能转为String。
    	//所以,我们在写集合的时候,最好将泛型加上去,也就是在集合后面指定该存储的类型。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    泛型:当我们写集合时候,不在集合后面加<>,这样的话,当我们在集合中增加多种数据时,如,整数、字符串等,就会发生报错,加上<>并指定数据类型,这样就可以把在编译之后报的错,提前到编译阶段,因为编译后的.class文件不会显示出泛型,我们又把编译阶段可能出现多种数据类型,对其在编译阶段就报错,这样就可以保证其安全性,这是在JDK1.5版本后加上的特性。

    /*
     *  将的酒店员工,厨师,服务员,经理,分别存储到3个集合中
     *  定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法
     */
    import java.util.ArrayList;
    import java.util.Iterator;
    public class GenericTest {
    	public static void main(String[] args) {
    		//创建3个集合对象
    		ArrayList<ChuShi> cs = new ArrayList<ChuShi>();
    		ArrayList<FuWuYuan> fwy = new ArrayList<FuWuYuan>();
    		ArrayList<JingLi> jl = new ArrayList<JingLi>();
    		
    		//每个集合存储自己的元素
    		cs.add(new ChuShi("张三", "后厨001"));
    		cs.add(new ChuShi("李四", "后厨002"));
    		
    		fwy.add(new FuWuYuan("翠花", "服务部001"));
    		fwy.add(new FuWuYuan("酸菜", "服务部002"));
    		
    		jl.add(new JingLi("小名", "董事会001", 123456789.32));
    		jl.add(new JingLi("小强", "董事会002", 123456789.33));
    		
    //		ArrayList arrayString = new ArrayList();
    		iterator(jl);
    		iterator(fwy);
    		iterator(cs);
    	
    	}
    	/*
    	 * 定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法 work
    	 * ? 通配符,迭代器it.next()方法取出来的是Object类型,怎么调用work方法
    	 * 强制转换:  it.next()=Object o ==> Employee
    	 * 方法参数: 控制,可以传递Employee对象,也可以传递Employee的子类的对象
    	 * 泛型的限定  本案例,父类固定Employee,但是子类可以无限?
    	 *   ? extends Employee 限制的是父类, 上限限定, 可以传递Employee,传递他的子类对象
    	 *   ? super   Employee 限制的是子类, 下限限定, 可以传递Employee,传递他的父类对象
    	 * 不写继承Employee的话什么参数都能传进来,如,ArrayList array = new ArrayList();
    	 */
    	 
    	public static void iterator(ArrayList<? extends Employee> array){
    		
    		 Iterator<? extends Employee> it = array.iterator();
    		 while(it.hasNext()){
    			 //获取出的next() 数据类型,是什么Employee
    			 Employee e = it.next();
    			 e.work();
    		 }
    	}
    }
    
    • 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
    /*
     *  List接口派系, 继承Collection接口
     *    下面有很多实现类
     *  List接口特点: 有序,索引,可以重复元素
     *    实现类, ArrayList, LinkedList
     *    
     *  List接口中的抽象方法,有一部分方法和他的父接口Collection是一样
     *  List接口的自己特有的方法, 带有索引的功能
     */
    public class ListDemo {
    	public static void main(String[] args) {
    		function_2();
    	}
    	/*
    	 *  E set(int index, E)
    	 *  修改指定索引上的元素
    	 *  返回被修改之前的元素
    	 */
    	public static void function_2(){
    		List<Integer> list = new ArrayList<Integer>();
    		list.add(1);
    		list.add(2);
    		list.add(3);
    		list.add(4);
    		
    		Integer i = list.set(0, 5);
    		System.out.println(i);
    		System.out.println(list);
    	}
    	
    	
    	/*
    	 *  List接口中的方法:
    	 *  set和add有区别,虽然都可以按照索引导入数
    	 *	据,但是set不能超过数组长度去导入数据,
    	 *	就是说set只能在原有的数组中进行导入,而
    	 *	add可以。
    	 *  
    	 */
    	 
    	 
    	/*
    	 *  E remove(int index)
    	 *  移除指定索引上的元素
    	 *  返回被删除之前的元素
    	 */
    	public static void function_1(){
    		List<Double> list = new ArrayList<Double>();
    		list.add(1.1);
    		list.add(1.2);
    		list.add(1.3);
    		list.add(1.4);
    		
    		Double d = list.remove(0);
    		System.out.println(d);
    		System.out.println(list);
    	}
    	
    	/*
    	 *  add(int index, E)
    	 *  将元素插入到列表的指定索引上
    	 *  带有索引的操作,防止越界问题
    	 *  java.lang.IndexOutOfBoundsException
    	 *     ArrayIndexOutOfBoundsException
    	 *     StringIndexOutOfBoundsException
    	 */
    	public static void function(){
    		List<String> list = new ArrayList<String>();
    		list.add("abc1");
    		list.add("abc2");
    		list.add("abc3");
    		list.add("abc4");
    		System.out.println(list);
    		
    		list.add(1, "itcast");
    		System.out.println(list);
    	}
    }
    
    • 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

    遍历数组有三种方法:

    第一种:迭代方法

    //迭代是反复内容,使用循环实现,循环的条件,集合中没元素, hasNext()返回了false
    		while(it.hasNext()){
    			String s = it.next();
    			System.out.println(s);
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第二种:for循环

    for(int i = 0; i < list.size(); i++){
    	String str = list.get(i);
    	System.out.println(str);
    }
    
    • 1
    • 2
    • 3
    • 4

    第三种:增强的for循环

    for(String s : str){
    			System.out.println(s.length());
    		}
    
    • 1
    • 2
    • 3

    集合

    ArrayList集合适用于查询操作的时候,LinkedList集合适用于增删操作LinkedList详细信息

    set和list的区别,set不能存储同样的数据,list可以

    Map遍历方式

    public class EntryDemo {
    	public static void main(String[] args) {
    		Map<Integer,String> map = new HashMap<Integer,String>();
    		map.put(1, "2ad");
    		map.put(2, "23d");
    		map.put(3, "12ad");
    		Set<Map.Entry<Integer,String>> set = map.entrySet();
    		Iterator<Map.Entry<Integer, String>> it = set.iterator();
    		while(it.hasNext()){
    			Entry<Integer, String> next = it.next();
    			Integer key = next.getKey();
    			String value = next.getValue();
    			System.out.println(key+value);
    		}
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    public class EntryDemo {
    	public static void main(String[] args) {
    		Map<String,Integer> map = new HashMap<String,Integer>();
    		map.put("2ad", 1);
    		map.put("23d", 2);
    		map.put("12ad", 3);
    		Set<String> keySet = map.keySet();
    		Iterator<String> iterator = keySet.iterator();
    		while(iterator.hasNext()){
    			String next = iterator.next();
    			System.out.println(next);
    		}
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    或者用增强for

    for(Map.Entry<String, Integer> entry : map.entrySet()){
    			System.out.println(entry);
    		}
    
    • 1
    • 2
    • 3

    注意:增强for不能遍历map,我们上面这个例子是遍历set,通过间接遍历map,不能直接遍历map。
    理由:因为Iterable下面没有Map什么事,所以增强for不能遍历map。

    注意点:
    在这里插入图片描述
    当我们把String写后面不写前面时候,这样遍历的结果,即使有重复的,也会直接打印输出出来。
    此时解决方法:可以在Person类中重写hashCode和equals方法,即可解决出现重复数据的情况。

    在这里插入图片描述

    vector

    在这里插入图片描述
    在这里插入图片描述

    静态导入

    /*
     * JDK1.5新特性,静态导入
     * 减少开发的代码量
     * 标准的写法,导入包的时候才能使用
     * 
     * import static java.lang.System.out;最末尾,必须是一个静态成员
     */
    import static java.lang.System.out;
    import static java.util.Arrays.sort;
    
    
    public class StaticImportDemo {
    	public static void main(String[] args) {
    		out.println("hello");
    		
    		int[] arr = {1,4,2};
    		sort(arr);
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    可变参数

    /*
     *  JDK1.5新的特性,方法的可变参数
     *  前提: 方法参数数据类型确定,参数的个数任意
     *  可变参数语法: 数据类型...变量名
     *  可变参数,本质就是一个数组
     */
    public class VarArgumentsDemo {
    	public static void main(String[] args) {
    		//调用一个带有可变参数的方法,传递参数,可以任意
    	//	getSum();
    		int sum = getSum(5,34,3,56,7,8,0);
    		System.out.println(sum);
    		
    		function(1,2,3);
    	}
    	/*
    	 * 可变参数的注意事项
    	 * 1. 一个方法中,可变参数只能有一个
    	 * 2. 可变参数,必须写在参数列表的最后一位
    	 */
    	 public static void function(Object...o){
    		 
    	 }
    	 public static void function(int a,int b,int...c){
    		 
    	 }
    	
    	/*
    	 * 定义方法,计算10个整数和
    	 * 方法的可变参数实现
    	 */
    	public static int getSum(int...a){
    		int sum = 0 ;
    		for(int i : a){
    			sum = sum + i;
    		}
    		return sum;
    	}
    }
    
    • 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

    线程安全
    在这里插入图片描述

    Map嵌套案例

    /*
     *  Map集合的嵌套,Map中存储的还是Map集合
     *  要求:
     *    传智播客  
     *      Java基础班
     *        001  张三
     *        002  李四
     *      
     *      Java就业班
     *        001  王五
     *        002  赵六
     *  对以上数据进行对象的存储
     *   001 张三  键值对
     *   Java基础班: 存储学号和姓名的键值对
     *   Java就业班:
     *   传智播客: 存储的是班级
     *   
     *   基础班Map   <学号,姓名>
     *   传智播客Map  <班级名字, 基础班Map>
     */
    public class MapMapDemo {
    	public static void main(String[] args) {
    		//定义基础班集合
    		HashMap<String, String> javase = new HashMap<String, String>();
    		//定义就业班集合
    		HashMap<String, String> javaee = new HashMap<String, String>();
    		//向班级集合中,存储学生信息
    		javase.put("001", "张三");
    		javase.put("002", "李四");
    		
    		javaee.put("001", "王五");
    		javaee.put("002", "赵六");
    		//定义传智播客集合容器,键是班级名字,值是两个班级容器
    		HashMap<String, HashMap<String,String>> czbk =
    				new HashMap<String, HashMap<String,String>>();
    		czbk.put("基础班", javase);
    		czbk.put("就业班", javaee);
    		
    		//keySet(czbk);
    		entrySet(czbk);
    	}
    	
    	public static void entrySet(HashMap<String,HashMap<String,String>> czbk){
    		//调用czbk集合方法entrySet方法,将czbk集合的键值对关系对象,存储到Set集合
    		Set<Map.Entry<String, HashMap<String,String>>> 
    		                         classNameSet = czbk.entrySet();
    		//迭代器迭代Set集合
    		Iterator<Map.Entry<String, HashMap<String,String>>> classNameIt = classNameSet.iterator();
    		while(classNameIt.hasNext()){
    			//classNameIt.next方法,取出的是czbk集合的键值对关系对象
    			Map.Entry<String, HashMap<String,String>> classNameEntry =  classNameIt.next();
    			//classNameEntry方法 getKey,getValue
    			String classNameKey = classNameEntry.getKey();
    			//获取值,值是一个Map集合
    			HashMap<String,String> classMap = classNameEntry.getValue();
    			//调用班级集合classMap方法entrySet,键值对关系对象存储Set集合
    			Set<Map.Entry<String, String>> studentSet = classMap.entrySet();
    			//迭代Set集合
    			Iterator<Map.Entry<String, String>> studentIt = studentSet.iterator();
    			while(studentIt.hasNext()){
    				//studentIt方法next获取出的是班级集合的键值对关系对象
    				Map.Entry<String, String> studentEntry = studentIt.next();
    				//studentEntry方法 getKey getValue
    				String numKey = studentEntry.getKey();
    				String nameValue = studentEntry.getValue();
    				System.out.println(classNameKey+".."+numKey+".."+nameValue);
    			}
    		}
    			System.out.println("==================================");
    		
    		for (Map.Entry<String, HashMap<String, String>> me : czbk.entrySet()) {
    			String classNameKey = me.getKey();
    			HashMap<String, String> numNameMapValue = me.getValue();
    			for (Map.Entry<String, String> nameMapEntry : numNameMapValue.entrySet()) {
    				String numKey = nameMapEntry.getKey();
    				String nameValue = nameMapEntry.getValue();
    				System.out.println(classNameKey + ".." + numKey + ".." + nameValue);
    			}
    		}
    	}
    	
    	public static void keySet(HashMap<String,HashMap<String,String>> czbk){
    		//调用czbk集合方法keySet将键存储到Set集合
    		Set<String> classNameSet = czbk.keySet();
    		//迭代Set集合
    		Iterator<String> classNameIt = classNameSet.iterator();
    		while(classNameIt.hasNext()){
    			//classNameIt.next获取出来的是Set集合元素,czbk集合的键
    			String classNameKey = classNameIt.next();
    			//czbk集合的方法get获取值,值是一个HashMap集合
    			HashMap<String,String> classMap = czbk.get(classNameKey);
    			//调用classMap集合方法keySet,键存储到Set集合
    			Set<String> studentNum = classMap.keySet();
    			Iterator<String> studentIt = studentNum.iterator();
    	   
         	   while(studentIt.hasNext()){
    				//studentIt.next获取出来的是classMap的键,学号
    				String numKey = studentIt.next();
    				//调用classMap集合中的get方法获取值
    				String nameValue = classMap.get(numKey);
    				System.out.println(classNameKey+".."+numKey+".."+nameValue);
    			}
    		}
    		
    		System.out.println("==================================");
    	    for(String className: czbk.keySet()){
    	       HashMap<String, String> hashMap = czbk.get(className);	
    	       for(String numKey : hashMap.keySet()){
    	    	   String nameValue = hashMap.get(numKey);
    	    	   System.out.println(className+".."+numKey+".."+nameValue);
    	       }
    	    }
    	}
    
    }
    
    • 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

  • 相关阅读:
    泛型的继承、通配和练习
    C#(三十八)之StreamWriter StreamWriter使用方法及与FileStream类的区别
    电商API:淘宝京东拼多多1688多电商平台的商品销量库存信息获取
    uniapp 在父组件中使用ref属性调用子组件中的方法 报错undefined
    c编译器学习02:chibicc文档翻译
    计算机毕业设计ssm电商后台系统c83si系统+程序+源码+lw+远程部署
    stm32之串口/蓝牙控制led灯
    《Java编程思想》读书笔记(四)
    c盘垃圾太多怎么清理?c盘垃圾太多需要重装系统嘛?
    半导体行业如何在跨网数据交换时保证核心数据是安全的?
  • 原文地址:https://blog.csdn.net/Thrive_LCX/article/details/137222852