##方法参数类型以及类型问题的研究

方法参数类型以及类型问题的研究

类名作为形式参数

A:案例:类名作为形式参数传递

当你以后看到一个方法的形参要一个类的类型,米酒传递该类的一个对象。

public class MyTest {
    public static void main(String[] args) {
        //以后如果你看的一个方法的形参要一个类,类型,那你就传递一个该类的对象
        Student student = new Student();
        show(new Student(), 20);
        student.setNum(40);
        System.out.println(student.num);//
    }

    public static void show(Student student, int num) {
        student.num = num;
    }
}

class Student {
    int num = 100;

    public void setNum(int num) {
        this.num = num;
    }
}

抽象类名作为形式参数

A:案例演示:抽象类名作为形式参数

当你看到一个方法的形参要一个抽象类的类型,你就传递一个该类的子类对象。

public class MyTest2 {
    public static void main(String[] args) {
        //如果你以后看的一个方法的形参,要一个抽象类 类型,你就传递一个该类的子类对象。
        BB bb = new BB();
        show(bb, 50);
        System.out.println(bb.num); //
        bb.aa();
    }

    public static void show(AA aa, int num) {
        aa.num = num;

    }
}

abstract class AA {
    int num = 100;

    public abstract void aa();
}

class BB extends AA {
    int num = 20;

    @Override
    public void aa() {
        System.out.println(super.num);
    }
}

接口名作为形式参数

A:案例演示:接口名作为形式参数

当你以后看到一个方法的形参要一个接口类型,你就传递一个该接口的子类对象

public class MyTest {
    public static void main(String[] args) {
        //如果你以后看到一个方法的形参,要一个接口类型,你就传一个该接口的子类对象。
        MyClass myClass = new MyClass();
        show(myClass);
        myClass.setNum(500);
        System.out.println(myClass.num); //2. 500
        System.out.println(MyInterface.num); //3. 100
    }

    public static void show(MyInterface myInterface) { //MyInterface myInterface=myClass
        System.out.println(myInterface.num); //1. 100
    }
}

interface MyInterface {
    public static final int num = 100;

    void aa();
}

//ctrl+I 重写父接口的方法
//ctrl+O 重写父类的方法
class MyClass implements MyInterface {
    int num = 20;

    public void setNum(int num) {
        this.num = num;
    }

    @Override
    public void aa() {
        System.out.println(num);
    }
}

类名作为返回值类型

A:案例演示:类名作为返回值类型

当你以后看到一个方法的返回值类型是一个类类型,你就返回一个该类的对象

public class MyTest {
    public static void main(String[] args) {
        Student student = getStudent();
        student.setNum(80);
        int num = student.getNum();
        System.out.println(num); //80
    }

    //如果你以后看到一个方法的返回值类型,要一个类 类型,你就返回一个改类的对象。
    public static Student getStudent() {
        Student student = new Student();
        student.num = 50;
        return new Student();
    }
}

class Student {
    int num = 20;

    public void setNum(int num) {
        this.num = num;
    }

    public int getNum() {
        return num;
    }
}

接口作为返回值

A:案例演示:接口名作为返回值

当你以后看到一个返回值的类型,是一个接口类型,你就返回一个该类的子类对象。

public class MyTest3 {
    public static void main(String[] args) {
        Myinterface myinterface = test(8);
        System.out.println(myinterface.num); //100
        System.out.println(Myinterface.num); //100
        BB bb = (BB) myinterface;
        System.out.println(bb.num); //8
    }

    //如果你以后看到一个方法的返回值类型,要一个接口类型,你就返回该接口的子类对象。
    public static Myinterface test(int num) {
        BB bb = new BB();
        bb.num = num;
        return bb;
    }
}

interface Myinterface {
    int num = 100;

    public abstract void show(int num);
}

class BB implements Myinterface {
    int num = 20;


    @Override
    public void show(int num) {
        System.out.println(num);
    }
}

抽象类名作为返回值类型

A:案例演示:抽象类名作为返回值类型

当你以后看到一个方法的返回值是一个抽象类类型,你就返回一个一个该抽象类的子类对象

public class MyTest2 {
    public static void main(String[] args) {
        CC cc = test();
        cc.num = 500;
        cc.cc(); //120
        System.out.println(cc.num);//500
    }

    //如果你以后看到一个方法的返回值类型,要一个抽象类 类型,你就返回一个改类的子类对象。
    public static CC test() {
        MyClass myClass = new MyClass();
        myClass.num = 120;
        return myClass;
    }
}

abstract class CC {
    int num = 20;

    public abstract void cc();
}

class MyClass extends CC {
    int num = 10;

    @Override
    public void cc() {
        System.out.println(num);
    }
}

链式编程

A:案例演示:链式编程

public class MyTest {
    public static void main(String[] args) {
        //链式编程风格
        //当你调用完一个方法,这个方法的返回值是个对象,那么你可以继续打点,调用该对象中的方法。
        int num = new Student().getStudent(new Student(), 800).getStudent(new Student(), 9000).getNum();

        System.out.println(num);


        /*
        Student student = new Student();
        Student student1 = student.getStudent(new Student(), 800);
        Student student2 = student1.getStudent(new Student(), 9000);
        int num1 = student2.getNum();
        System.out.println(num1);*/

    }
}

class Student {
    int num = 10;

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public Student getStudent(Student student, int num) {
        student.num = num;
        Student student1 = new Student();
        student1.setNum(900);
        return student;
    }
}

package关键字的概述及作用

A:包的作用:就是文件夹

B:包的作用:用来解决同一个路径下不能存在同名文件的问题(分类管理)

C : 包的划分:

​ 按照功能

​ 按照模块

包的定义以及注意事项

A:定义包的格式

​ package包名;

​ 多级包用分开即可

B: 定义包的注意事项

​ 1 :package语句必须是程序的第一条可执行的代码

​ 2 : package语句在Java文件中方只能有一个

​ 3 :如果没有package,默认没有包名

C:案例演示

​ 包的定义以及注意事项


不同包下类之间的访问

A:案例演示

​ 不同包下之间的访问

​ 定义两个类:Demo,Ttst.

​ Demo

​ 求和方法(sum)

​ Test

​ 测试方法(main)

import关键字的概述和使用

A:导包的概述

​ 不同包下的类之间的访问,我们发现,每次使用不同包下 的类的时候,都需要加包的全路径。比较麻烦。这个时候。Java就提供了导包的功能

四种权限修饰符的测试

A:案例演示

​ 四种权限修饰符:private(私有的),默认,protected(受保护的),public(公共的)

B:结论

​ 本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)

​ private Y
​ 默认 Y Y
​ protected Y Y Y
​ public Y Y Y Y

类及其组成所使用的常见修饰符

A:权限修饰符:private,默认的,protected,public

​ 状态修饰符:static,final

​ 抽象修饰符:abstract

B:修饰类的关键字

​ 权限修饰符:默认修饰符,public

​ 状态修饰符:final

​ 抽象类修饰符:abstract

C:修饰成员变量的关键字

​ 权限修饰符:private,默认的,protected,public

​ 状态修饰符:static,final

​ 用的最多就是:private

D:修饰构造方法的关键字

​ 权限修饰符:private,默认的,protected,public

E:修饰成员方法的关键字

​ 权限修饰符:private,默认的,protected,public

F:除此以外的组合规则:

​ 成员变量:public static final

​ 成员方法:public static

​ public abstract

​ public final

内部类概述和访问特点

A:内部类概述:把类定义在其他类的内部,这个类被称为内部类。

​ 举例:在A中定义一个一个类B,类B就是内部类。

B:内部类的访问特点

​ a:累不类可以直接访问外部类的成员,包括私有。

​ b:外部类要访问内部类的成员,必须创建对象。

C:案例演示

​ 累不类及其 访问的特点

public class MyTest {
    public static void main(String[] args) {
        /*
         *  内部类:将一个类定义到另一个类的内部
         * 比如 将 类 A 定义到类B的内部,那么A类就是内部类,可以把B叫做外部类
         * 根据内部类定义的位置不同可以分为:成员内部类和局部内部类
         * 成员内部类:将内部类定义到外部类的成员位置
         * 局部内部类:将内部类定义到外部类的局部位置
         *
         *
         * */


    }
}

//外部类
class B {
    //成员内部类
    class A {


    }

    public void show() {
        //局部内部类
        class C {

        }
    }
}


public class MyTest {
    public static void main(String[] args) {
        //成员内部类
        Wai wai = new Wai();
        wai.waiShow();
        //调用内部类的成员,得创建内部类的对象。
        Wai.Nei nei = new Wai().new Nei(); //创建成员内部类对象的语法

        nei.neiShow();

        //内部类的特点
        //1.可以直接访问外部类的成员,包括私有成员。

    }
}

class Wai {
    int num = 100;
    private double a = 2.5;

    class Nei {
        int b = 20;

        public void neiShow() {
            System.out.println("内部类的成员方法" + b);
        }

        public void neiTest() {
            //1. 可以直接访问外部类的成员,包括私有成员。
            System.out.println(num);
            System.out.println(a);
            waiShow();
            waiTest();
        }


    }

    public void waiShow() {
        System.out.println("外部类的show方法");
    }

    private void waiTest() {
        System.out.println("外部类的私有的方法");
    }

    public void hehe() {
        //外部类要方位内部类的成员得创建内部类的对象
        Nei nei = new Nei();
        System.out.println(nei.b);
    }
}




内部类分类及其成员内部类的直接使用

A:按照内部类位置分类

​ 成员位置:在成员位置定义的类,被称为成员内部类。

​ 局部位置:在局部位置定义的类,被称为局部内部类。

B:成员内部类

​ 如何在测试类直接访问内部类的成员。

​ 格式: 外部类名.内部 类名 对象名=外部类对象.内部类对象;

public class MyTest {
    public static void main(String[] args) {
      /*
      私有的内部类,外界无法直接创建其对象呢
      Outer.Inner inner = new Outer().new Inner();
        inner.neiShow();*/

        Outer outer = new Outer();
        outer.waiShow();


    }
}

class Outer {
    int num = 10;

    //私有的内部类
    private class Inner {
        int a = 20;

        public void neiShow() {
            System.out.println(a);
            System.out.println(num);
        }

    }

    public void waiShow() {
        Inner inner = new Inner();
        inner.neiShow();
    }
}

成员内部 类的权限修饰符及其应用

A:成员内部类的修饰符:

​ private 为了保证数据的安全性

​ static 为了方便访问数据

​ 注意事项:a:静态内部类的访问的外部类数据必须用静态修饰

​ b:成员方法可以是静态的也可以是非静态的

B:成员内部类被静态修饰后的访问方式是:

​ 格式:外部类名.内部类名 对象名=new 外部类名.内部类名();

public class MyTest {
    public static void main(String[] args) {
        //静态的内部类,创建对象的语法
        Wai.Nei nei = new Wai.Nei();
        //静态的内部类,只能访问外部类的静态成员
    }
}

class Wai {
    private static int num = 20;

    //静态的内部类
    static class Nei {
        public static void neiShow() {
            System.out.println(num);

        }

        public void neiTest() {

        }
    }

    public void waiShow() {

    }
}

成员内部 类的题目理解

A:案例

class Outer {
    public int num = 10;

    class Inner {
        public int num = 20;

        public void show() {
            int num = 30;
            System.out.println(num);  //30
            System.out.println(this.num); //20
            //System.out.println(new Outer().num); //10
            //记住这个语法:外部类名.this  表示获取的是外部类对象。
            System.out.println(Outer.this.num);
        }
    }
}

class InnerClassTest {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer().new Inner();
        oi.show();
    }
}

局部内部 类访问局部变量的问题

A : 可以直接访问外部类的成员

B:可以创建内部类的对象,通过对象调用内部类的方法,来使用局部内部类的功能

C:局部内部类访问局部变量必须用final修饰

​ 原因是局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。

​ 为了让数据还能继续使用,就用final修饰,这样堆内存存储的其实是一个常量值。

JDK1.8之后,final会自动加上,你不用手动其加,但是你要知道

public class MyTest {
    public static void main(String[] args) {

    }
}

class Oueter {

    public void show(final int a, final int b) {
        //局部变量
        final int num = 20;
        //局部内部类访问外部类的局部变量,局部变量必须用final修饰,使其变为常量。JDK1.8 这个final默认就加上了。
        ///*
        //  为什么呢?
        //   	因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。
        // 	为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。
        // 	JDK1.8之后,final会默认加上,你不用手动去加,但是你要知道
        //
        // */
        class Inner {
            public void neiShow() {
                System.out.println(num);
                System.out.println(a);
                System.out.println(b);
            }
        }
    }
}

匿名内部类的格式和理解

A:匿名内部类:就是局部内部类的简化写法。

B:前提:存在一个接口或者类;这里的类可以是具体类也可以是抽象类。

C:格式:

​ new 类名或者接口名(){

重写方法;

};

D:本质:就是一个继承了该类或者实现了该接口的子类匿名对象。

E:案例演示

​ 碍不着要求来一个匿名内部类

public class MyTest {
    public static void main(String[] args) {

        //匿名内部类:他本质上是一个对象,是谁的对象?是实现了该接口或继承了该类的子类对象。
        //我想要一个Animal的子类对象
        Dog dog = new Dog();
        dog.eat();
/*
* new 类名或者接口名(){
		重写方法;
	} ;
* */
        new Animal() {
            @Override
            public void eat() {
                System.out.println("吃饭");
            }
        };

        new Animal() {
            @Override
            public void eat() {
                System.out.println("吃饭222222");
            }
        }.eat();
    }
}


abstract class Animal {
    public abstract void eat();
}

class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("asdfasdfasdf");
    }
}

匿名内部类的方法调用

A:案例演示:匿名内部类的方法调用

public class MyTest {
    public static void main(String[] args) {
        new Animal() {

            @Override
            public void eat() {
                System.out.println("猫吃鱼");
            }

            @Override
            public void sleep() {
                System.out.println("猫白天睡觉");
            }
        }.sleep();

        new Animal() {

            @Override
            public void eat() {
                System.out.println("猫吃鱼2222");
            }

            @Override
            public void sleep() {
                System.out.println("猫白天睡觉333333");
            }
        }.eat();
        System.out.println("==========================================================");
        Animal an = new Animal() {

            @Override
            public void eat() {
                System.out.println("猫吃鱼222288888888");
            }

            @Override
            public void sleep() {
                System.out.println("猫白天睡觉3333338888888888");
            }
        };

        an.eat();
        an.sleep();
    }
}

abstract class Animal {
    public abstract void eat();

    public abstract void sleep();
}

匿名内部类在开发中的应用

A:问题

​ 首先回顾我们曾经讲过的方法的形式参数引用类型的情况,

​ 我们知道这里需要一个子类对象,而匿名内部类就是一个子类匿名对象,所以,可以使用匿名内部类改进以前的方法

B:代码如下
//这里写抽象类,接口都行

	abstract class Person {
		public abstract void show();
	}
	 PersonDemo {
		public void method(Person p) {
			p.show();
		}
	}

	class PersonTest {
		public static void main(String[] args) {
			//如何调用PersonDemo中的method方法呢?
			
		}
	}	
	
interface Inter {
    void show();
}

class Outer {
    //补齐代码
    public static Inter method() {
        return new Inter() {
            @Override
            public void show() {
                System.out.println("Hello World");
            }
        };
    }
}

class OuterDemo {
    public static void main(String[] args) {
        //要求在控制台输出 "HelloWorld"
        Outer.method().show();
    }
}

匿名内部类中的关键字this

A:
interface Inter {
public static final int a = 23 ;
}

 interface Inter {
		public static final int a = 23 ;
	}
	
public class Test {

	public static void main(String[] args) {
		new Inter() {
			public void show() {
				//this 代表匿名内部类
				System.out.println(this.a);//23
	
			}
		}.show();
	}
}

匿名内部类的面试题

A:面试题
	按照要求,补齐代码
	interface Inter { 
		void show(); 
	}
	
	class Outer { 
		//补齐代码
        
 public static Inter method() {
        return new Inter() {
            @Override
            public void show() {
                System.out.println("Hello World");
            }
        };
    }
	}
	
	class OuterDemo {
		public static void main(String[] args) {
			  Outer.method().show();
		  }
	}
	要求在控制台输出”HelloWorld”

##12

API概述以及object类的概述

A:API(Application Programming Interface)
应用程序编程接口
B:Java API
就是Java提供给我们使用的类,这些类将底层的实现封装了起来,
我们不需要关心这些类是如何实现的,只需要学习这些类如何使用。
C:Object类概述
类层次结构的根类
所有类都直接或者间接的继承自该类
D:构造方法
public Object()
回想面向对象中为什么说:
子类的构造方法默认访问的是父类的无参构造方法

public class MyTest extends Object {

    public static void main(String[] args) {
        //Object:是所有类的顶层父类,所有的类都是直接或间接继承自他
        Object obj = new Object();
        System.out.println(obj);
        int i = obj.hashCode();
        System.out.println(i);

        Object obj2 = new Object();
        System.out.println(obj2);
        System.out.println(obj2.hashCode());

        //不同对象的hash码值是不一样。

        Student student = new Student();
        int i1 = student.hashCode();
        System.out.println(i1);


    }
}

0bject类的hashcode方法

A:案例:

​ public int hashCode ()

​ 1.返回对象的哈希码值,默认情况下,该方法会根据对象的地址来计算

​ 2.不停对象的哈希码值是不一样的

​ 但是同一个对象的哈希码值肯定相同

​ 3.不同对象的实际地址值,可以理解为逻辑地址值

public class MyTest extends Object {

    public static void main(String[] args) {
        //Object:是所有类的顶层父类,所有的类都是直接或间接继承自他
        Object obj = new Object();
        System.out.println(obj);
        int i = obj.hashCode();
        System.out.println(i);

        Object obj2 = new Object();
        System.out.println(obj2);
        System.out.println(obj2.hashCode());

        //不同对象的hash码值是不一样。

        Student student = new Student();
        int i1 = student.hashCode();
        System.out.println(i1);


    }
}

object类的getclass()方法

A:案例

​ public final class getclass()

​ 1.返回此object的运行时类

​ 2.可以通过抽拉式三类中的一个方法,获取对象的真实类的全名称

​ public string getname()

public class MyTest2 {
    public static void main(String[] args) {
        Object obj = new Object();

        /*Object.java-----Object.class-----当Object.class加载进内存,他会把Object.class也看做对象,所以会创建字节码文件对象
                ---- 我们可以通过 getClass()方法,来获取字节码文件对象

                Class 这个就是描述 字节码文件类型的 。
        */

        Object obj2 = new Object();

        //获取该类的自己码文件对象
        Class<?> aClass = obj.getClass();
        Class<?> aClass1 = obj2.getClass();

        System.out.println(obj == obj2); //false
        System.out.println(aClass == aClass1); //true


    }
}

object类的toString()方法

A:案例演示
public String toString()
a:返回该对象的字符串表示。
源代码:
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
b:它的值等于:
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
c:由于默认情况下的数据对我们来说没有意义,一般建议重写该方法。
怎么重写, 一般是将该类的所有的成员变量组成返回即可
B:最终版
自动生成
C: 直接输出对应的名称,就是调用对象的toString()方法

###object类的equals()方法

A:案例

​ 1.指示它某个对象是否与此对象相等

​ 源代码

			public boolean equals(Object obj) {
					return (this == obj);
			}
			
			
public class MyTest2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //当以后我们输出一个对象名时,没有看的地址值,说名该类重写了父类Object的toString();
        System.out.println(scanner.toString());

    }
}

​ 2.默认情况下比较的是对象的应用是否相同

​ 3.由于比较对象的引用没有意义,一般建议重写该方法。一般用于比较成员变量的值是否相同

​ 4.==比较引用类型的时候比较的是地址值是否相同,equals比较string和Interde 时候是

Object类的equals()方法代码优化)

A:案例演示
	Object类的equals()方法代码优化
		a: 提高效率
		b: 提高健壮性(instanceof)	
B:最终版
	自动生成
	
	public class MyTest {
    public static void main(String[] args) {
        Object obj = new Object();
        Object obj2 = new Object();

        System.out.println(obj == obj2);

        boolean b = obj.equals(obj2);

      /*  public boolean equals (Object obj){
            return (this == obj);
        }*/

        System.out.println(b);

        Student s1 = new Student();
        Student s2 = new Student();
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
        System.out.println(s1.equals(s1));


        //Object 类中的equals()方法,默认是在比较两个对象的地址值,是否相同。
        //有些子类认为老是比较地址值是否相同,他认为没有意义,所以有些子类想要按照他自己的比较方式去比较,
        //所以有些子类就会重写equals()方法按照自己的比较方式去比较。


    }
}



public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(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 boolean equals(Object obj) {// Object obj=s2
        //严谨性(考虑周全)提高方法的健壮性  性能方面的提高
        // 我们自定义的类,他认为 如果两个对象的成员变量值一摸一样,就认为这两个对象是相同的。
        //向下转型
        //instanceof 判断一个对象(引用)是不是该类型的一个引用(对象)
        if (obj == null) {
            return false;
        }
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof Student)) {
            return false;
        }

        Student s2 = (Student) obj;
        //"张三"=="张三"  0x001==0x002
        //如果你要比较两个字符串,字面上的内容是否相同,要调用 equals(s2.name)方法来比较。
        //String类他重写了父类Object中的equals(s2.name)方法去比较两个字符串字面上的内容是否相同
        //"张三".equals("张三")
        return this.age == s2.age && this.name.equals(s2.name);

    }

  /*  public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }*/
}

public class MyTest2 {
    public static void main(String[] args) {
        //Object 类中的equals()方法,默认是在比较两个对象的地址值,是否相同。
        //有些子类认为老是比较地址值是否相同,他认为没有意义,所以有些子类想要按照他自己的比较方式去比较,
        //所以有些子类就会重写equals()方法按照自己的比较方式去比较。

        Student s1 = new Student("张三", 23);
        Student s2 = new Student("张三", 23);
        //我们自定义的类,他认为 如果两个对象的成员变量值一摸一样,就认为这两个对象是相同的。
        //ClassCastException 类型转换异常
        Scanner scanner = new Scanner(System.in);


        System.out.println(s1.equals(s1));


    }
}


object类的clone()方法

clone()的权限修饰符是受保护的,在用的时候,让该类重写该方法,并把 该方法的权限修饰符该为public

​ 对象的克隆

​ :浅克隆和深克隆

​ 使用clone()方法就是浅克隆的方式

对象浅克隆的注意细节:

A: 如果一个对象需要调用clone()方法克隆,那么该对象所属的类必须实现Cloneable接口

B:cloneable接口只是一个标识接口而已,没有任何方法。

C:对象的浅克隆如果克隆一个对象的时候,如果被克隆的对象中维护一个另外一个一个类的对象,者时候知识克隆另外一个对象的地址值,而没有把另外一个对象也克隆一份。

D:对象的浅克隆特不会调用构造方法。

public class MyTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Dog dog = new Dog("小白", 2);
        System.out.println(dog);
        Dog dog2 = (Dog) dog.clone();
        // dog2.name = "小黑";
        // dog2.age = 3;
        System.out.println(dog2);
        //1.你要调用clone()方法,你这个类先要重写父类的clone方法,重写逻辑还是调用父类的逻辑,把重写方法的权限修饰符改为public
        //2.该类要实现Cloneable这个接口,不然就会抛出 CloneNotSupportedException
        //3.调用clone()方法时,不会执行构造方法。

    }
}

//Cloneable 是一个标记接口 里面没有任何抽象方法让你实现,为了给类打一个标记,让JVM 支持克隆
class Dog implements Cloneable {
    String name;
    int age;

    public Dog() {
        System.out.println("空参数构造执行了");
    }

    public Dog(String name, int age) {
        System.out.println("有参数构造执行了");
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}








public class MyTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        /*
         * 使用clone()方法采用的是浅克隆的方式
         * 3. 对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,
         * 这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。
         * */
        DogFood dogFood = new DogFood("王中王");
        Dog dog = new Dog("小白", 2, dogFood);
        dog.dogFood.foodName = "玉米肠";
        Dog dog2 = (Dog) dog.clone();
        dog2.name = "小黑";
        dog2.age = 3;
        dog2.dogFood.foodName = "金锣火腿肠";

        System.out.println(dog.name); //小白
        System.out.println(dog.age); //2
        System.out.println(dog.dogFood.foodName); //玉米肠  金锣火腿肠

        System.out.println(dog2.name); //小黑
        System.out.println(dog2.age); //3
        System.out.println(dog2.dogFood.foodName); //金锣火腿肠 金锣火腿肠

    }
}

class Dog implements Cloneable {
    String name;
    int age;
    //维护了一个狗粮类的对象
    DogFood dogFood;

    public Dog() {

    }

    public Dog(String name, int age, DogFood dogFood) {
        this.name = name;
        this.age = age;
        this.dogFood = dogFood;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

//狗粮类
class DogFood {
    String foodName;

    public DogFood() {
    }

    public DogFood(String foodName) {
        this.foodName = foodName;
    }
}


String与Scanner

A:Scanner 概述:JDK1.5以后用于获取用户的键盘输入

B:Scanner人的构造方法

​ Scanner(InputStream source)

​ System类下有一个静态的字段:

​ public static final InputStream in;标准的输入流,对应着键盘的录入。

public class MyTest {
    public static void main(String[] args) {
        /*Scanner(InputStream source)
        构造一个新的 Scanner,它生成的值是从指定的输入流扫描的。*/
        //InputStream in = System.in;
        //“标准”输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入
        Scanner sc = new Scanner(System.in);
      /*  int i = sc.nextInt();
        long l = sc.nextLong();
        double v = sc.nextDouble();

        boolean b = sc.nextBoolean();

        String s = sc.nextLine();*/
        System.out.println("请输入一个整数");
        int i = sc.nextInt();


    }
}

Scanner类的hashNextxxx()和nextxxx()方法的讲解

A:基本格式hashnextXxx() 判断是否是某种类型的元素,其中xxx可以是Int,double等

​ 如果需要判断是否包含一个字符串,可以省略Xxx

nextXxx()获取下一个输入项。X小写的含义和上个方法的Xxx相同

B:案例

​ 演示结合判断获取数据的情况

public class MyTest2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个整数");
        // hasNextXxx() 判断下一个是否是某种类型的元素, 其中Xxx可以是Int, Double等。
        // 如果需要判断是否包含下一个字符串,则可以省略Xxx
        // nextXxx() 获取下一个输入项。Xxx的含义和上个方法中的Xxx相同
        if (sc.hasNextInt()) {
            int num = sc.nextInt();
            System.out.println(num);
        } else {
            System.out.println("你输入的类型不正确");
        }
    }
}

Scanner获取数据出现的小问题以及解决方案

A:两个常用的方法:

​ public int nextInt();获取一个int类型的值

​ public String nextLine();获取一个String类型的值

​ public String next();获取一个String类型的值

B:获取多个值的时候最好创建多个对象,避免出现问题。

public class MyTest3 {
    public static void main(String[] args) {
        //你先录入整数紧接着录入字符串,发现字符串没有录入,这是因为nextLine();把你之前敲得回车换行录入了
        //解决方案1:你在录入字符串时,在创建一个新的Scanner对象,一般我们采用这种
        //解决方案2:可以使用next()方法来录入字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个整数");
        int i = sc.nextInt();
        System.out.println(i);

        sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");

        // String s = sc.next();
        String s = sc.nextLine();
        System.out.println(s);

    }
}

String类的概述

A:什么是字符串

​ 字符串是多个字符串组成的一串数据

​ 字符串可以看成是字符数组

B:String类的概述

​ 通过JDK提供的API,查看String类的说明

​ 可以看到这样的两句话。

​ 1,字符串字面值”abc“也可以看成一个字符串对象。

​ 2,字符串是常量,一旦被创建,就不能被改变。

public class MyTest {
    public static void main(String[] args) {
        //String 表示字符串
        //字符串:由一个或多字符组成的有序序列。
        //String 类代表字符串。
        // 1.Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
        //2.字符串是常量;它们的值在创建之后不能更改。

        // String()
        // 初始化一个新创建的 String 对象,使其表示一个空字符序列。
        //采用空参构造创建String类的对象

        String s = new String();  //""

        //String类重写了toStrirng() 打印的是字符串的字面内容
        System.out.println(s); //

        System.out.println(""); //"" 空字符串

        // null 和 ""


        // String(String original)
        // 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。
        String s1 = new String("abc");
        System.out.println(s1);


    }
}

String类的构造方法

A:常见的构造方法

​ public String().空构造

​ public String(byte[] bytes).把字节数组转换为字符串

​ public String(byte[] bytes,int index,int length).把字节数组的一部分循环换为字符串(index表示从第几个索引开始,length表示的是长度)

​ public String(char[] vauel):把字节数组转换为字符串

​ public String (char[] value,int index, int count).把字符数组一部分转换为字符串

​ public String(String original).把字符串常量值转换为字符串

B:案例演示

String的常用构造方法

public class MyTest2 {
    public static void main(String[] args) {
        //public String( byte[] bytes):把字节数组转成字符串
        byte[] bytes = {97, 98, 99, 100};

        String s = new String(bytes);
        //
        System.out.println(s);
        //把字节数组的一部分转换成字符串,0 表示起始索引 2 表示个数
        String s2 = new String(bytes, 0, 2);
        System.out.println(s2);


        char[] chs = {'a', 'b', 'c', 'd', '我', '爱', '你'};
        // "abcd我爱你"
        //把字符数组转换成字符串
        String s1 = new String();
        for (int i = 0; i < chs.length; i++) {
            //打印看和获取到是两个概念
            s1 += chs[i];
        }

        System.out.println(s1);


       /* String( char[] value)
        分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
        String( char[] value, int offset, int count)
        分配一个新的 String,它包含取自字符数组参数一个子数组的字符。*/

        String s3 = new String(chs);
        System.out.println(s3);

        //把字符数组的一部分转换成字符串,4 起始索引 3 个数
        String s4 = new String(chs, 4, 3);
        System.out.println(s4);
        //length() 获取字符串的长度
        int length = s4.length();
        System.out.println(length);


    }
}

String的特点一旦被创建就不能改变

A:String 的特点:以但被创建就不能改变 因为字符串的值是在堆内存的常量池划分空间 分配地址值

B:案例

​ a:理解

​ String s=“hello”;

​ s=“world”+“java”;s的结果是多少?

worldjava

​ b:画内存图解释:内容不能变,引用可以变

String类的常见问题

A:面试题1
	String s = new String(“hello”)和String s = “hello”;的区别
	并画内存图解释。
B:面试题2
	==和equals()的区别?   
C:面试题3
	看程序写结果
public class MyTest2 {
    public static void main(String[] args) {
        String s = "hello";
        String s2 = "world";
        String s3 = "hello";
        String s4 = new String("hello");

        System.out.println(s == s2); //false

        System.out.println(s2 == s3); //false

        System.out.println(s4 == s); //false

        System.out.println(s4 == s3); //false

        System.out.println(s == s3); //true
    }
}

String类的判断功能

A:String类的判断功能

​ public Boolean equals(String obj). 比较字符串的内容区分大小写

​ public boolean equalsIgnoreCase(String str). 比较字符串的类容是否相同,忽略大小写

​ public Boolean contains(String str). 判断传递进来的字符串是否被包含

​ public Boolean startsWith(String str). 判断传递进来的字符串是否是字符串的开头

​ public Boolean endsWith(String str). 判断传递进来的字符串是否是字符串的结尾

​ public boolean isEmpty(). 判断字符串是否为空串

B:案例

​ 演示String类的判断功能

public class MyTest3 {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");

        System.out.println(s1 == s2); //false
        //String类重写了equals()方法,比较的是两个字符串字面上的内容是否相同
        System.out.println(s1.equals(s2)); //true

        String s3 = new String("hello");

        String s4 = "hello";

        System.out.println(s3 == s4); //false
        System.out.println(s3.equals(s4)); //true

        String s5 = "hello";
        String s6 = "hello";

        System.out.println(s5 == s6); //true
        System.out.println(s5.equals(s6)); //true
    }
}

public class MyTest2 {
    public static void main(String[] args) {
        //==和equals() 的区别 ?
        //  == 他是比较运算符,可以比较基本数据类型,也可以比较引用数据类型
        // == 比较基本数据类型 比较的是变量的值是否相同
        //== 比较基本数据类型,比较的是两个对象的地址值是否相同
      /*  int a = 20;
        int b =20;
        System.out.println(a==b);*/
        // equals() Object 类中的一个方法,他的默认比较方式,比较两个对象的地址值是否相同。
        //但是有些类会重写equals() 方法,按照他所重写的方式进行比较
        //String 类重写了equals() 方法 比较的是两个字符串字面上的内容是否相同。


    }
}

模拟用户登录

A:案例演示:	需求:模拟登录,给三次机会,并提示还有几次。
public class MyTest3 {
    public static void main(String[] args) {
        // A:
        // 案例演示:
        // 需求:模拟登录, 给三次机会, 并提示还有几次。
        String name = "zhangsan";
        String password = "123456";

        Scanner sc = new Scanner(System.in);
        for (int i = 1; i <= 3; i++) {
            System.out.println("请输入用户名");
            String uname = sc.nextLine();
            System.out.println("请输入密码");
            String upwd = sc.nextLine();
            if (uname.equals(name) && upwd.equals(password)) {
                System.out.println("登录成功");
                break;
            } else {
                if (i == 3) {
                    System.out.println("次数已经用完");
                } else {
                    System.out.println("用户名或密码错误,还剩余" + (3 - i) + "次");
                }

            }

        }
    }
}

String类的获取功能

A:String的获取功能:

public int length(): 获取字符串的长度

public char charAt(int intdex): 获取指定索引位置 的字符

public int indexof(int ch). 返回字符在此字符串中第一次出现的索引

public int indexof(char ch,int fromIndex). 返回指定的字符在指定位置后第一次出现的位置

public int indexOf(String str,int fromIndex): 返回指定字符串在此字符串中从指定位置后第一次出现处的索引。

public String substring(int start): 从指定位置开始截取字符串,默认到末尾。
public String substring(int start,int end): 从指定位置开始到指定位置结束截取字符串。(含头不含尾)

B:案例

演示String类的获取功能

public class MyTest {
    public static void main(String[] args) {
       /* public int indexOf ( int ch):返回指定字符在此字符串中第一次出现处的索引。
        public int indexOf (String str):返回指定字符串在此字符串中第一次出现处的索引。
        public int indexOf ( int ch, int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现处的索引。
        public int indexOf (String str,int fromIndex):返回指定字符串在此字符串中从指定位置后第一次出现处的索引。*/

        String s = "西部开源教育科技有限公开司";
        //返回指定字符在此字符串中第一次出现处的索引。如果没有找到返回 -1
        int index = s.indexOf('我');
        System.out.println(index);
        int i = s.indexOf("西部开源444");
        System.out.println(i);

        // int i1 = s.indexOf('开', 3);
        int i1 = s.indexOf('开', s.indexOf('开') + 1);
        System.out.println(i1);

        //lastIndexOf('开'); 从后往前找
        int i2 = s.lastIndexOf('开');
        System.out.println(i2);


        String s2 = "西部开源教育科技有限公开司";
        //根据起始索引和终止索引截取一部分字符串,含头不含尾
        String substring = s2.substring(0, 4);
        System.out.println(substring);
        //从起始索引截取完
        String substring1 = s2.substring(3);
        System.out.println(substring1);


    }
}

字符串的遍历

A:案例演示:	需求:遍历字符串
public class MyTest2 {
    public static void main(String[] args) {
        //1.反向遍历字符串
        //2.A:案例演示:	需求:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
        //3.判断某个字符是不是在这个字符串出现过一次
        String str = "asdfAASFsdfesadsSFFkKJDFk1255asdfasdf554755";
        //这段字符串中这个 一 是不是只出现了一次
        String str2 = "判断某个字符是不是在这个字符串出现过一次一次一次";

        for (int length = str2.length() - 1; length >= 0; length--) {
            char c = str2.charAt(length);
            System.out.println(c);
        }
        System.out.println("==============================================");

        int xiao = 0;
        int da = 0;
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (ch >= 'a' && ch <= 'z') {
                xiao++;
            } else if (ch >= 'A' && ch <= 'Z') {
                da++;
            } else {
                num++;
            }
        }

        System.out.println("小写字母" + xiao + "个");
        System.out.println("大写字母" + da + "个");
        System.out.println("数字" + num + "个");


        String str3 = "判断某个字符是不是在这个字符串出现过一次一次一次";

        if (str3.indexOf('一') == str3.lastIndexOf('一')) {
            System.out.println("出现过一次");
        } else {
            System.out.println("不止一次");
        }


    }
}

统计不同类型字符个数

A:案例演示:	需求:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
public class MyTest2 {
    public static void main(String[] args) {
        //1.反向遍历字符串
        //2.A:案例演示:	需求:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
        //3.判断某个字符是不是在这个字符串出现过一次
        String str = "asdfAASFsdfesadsSFFkKJDFk1255asdfasdf554755";
        //这段字符串中这个 一 是不是只出现了一次
        String str2 = "判断某个字符是不是在这个字符串出现过一次一次一次";

        for (int length = str2.length() - 1; length >= 0; length--) {
            char c = str2.charAt(length);
            System.out.println(c);
        }
        System.out.println("==============================================");

        int xiao = 0;
        int da = 0;
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (ch >= 'a' && ch <= 'z') {
                xiao++;
            } else if (ch >= 'A' && ch <= 'Z') {
                da++;
            } else {
                num++;
            }
        }

        System.out.println("小写字母" + xiao + "个");
        System.out.println("大写字母" + da + "个");
        System.out.println("数字" + num + "个");


        String str3 = "判断某个字符是不是在这个字符串出现过一次一次一次";

        if (str3.indexOf('一') == str3.lastIndexOf('一')) {
            System.out.println("出现过一次");
        } else {
            System.out.println("不止一次");
        }


    }
}

String类转换功能

A:String转换功能:

​ public byte[] getBytes(): 把字符串转换为字节数组。

​ public char[] tocharArray(): 把字符串转换为字符数组

​ public static String valueof(char[] zhs): 把字符数组转换为字符串。

​ public static String valueOf(int i): 把int类型的数据转成字符串。

​ 注意:String类的valueof方法可以把任意的类型转换为字符串。

​ public String toLowerCase(): 把字符串转换为小写

​ public String toUpperCase(): 把字符串转为大写

​ public String concat(String str) 把字符串拼接

B:案例

​ 案例演示String的转换功能

public class MyTest {
    public static void main(String[] args) {
        //getBytes() 把字符串转换成字节数组
    
        //把字节数组转换成字符串
    String str = "abcd";
        byte[] bytes = str.getBytes();
        for (int i = 0; i < bytes.length; i++) {
            System.out.println(bytes[i]);
        }

        String s = new String(bytes, 0, 2);
        System.out.println(s);

        //UTF-8 编码 一个汉字占3个字节
        //GBK 编码 一个汉字占2个字节

        String str2 = "asdfas";
        byte[] bytes1 = str2.getBytes();
        System.out.println(bytes1.length);
        String str3 = "asdfasdf";
        System.out.println(str3.getBytes().length);

    }
}

public class MyTest6 {
    public static void main(String[] args) {
        String str = "西部开源教育科技有限公司";
      /*  char[] chs=new char[str.length()];
        for (int i = 0; i < str.length(); i++) {
            chs[i]=str.charAt(i);
        }*/

        //toCharArray() 把字符串转换成字符数组
        char[] chars = str.toCharArray();
        //把字符数组转换成字符串
        String s = new String(chars);
        System.out.println(s);


    }
}

2

public class MyTest7 {
    public static void main(String[] args) {
        int num = 100;  //"100"
        String str = num + ""; //拼空串
        String s = String.valueOf(num);
        boolean b = true; //"true"
        System.out.println(String.valueOf(b));
        //
        String s1 = String.valueOf(new char[]{'a', 'b', 'c'});
        System.out.println(s1);
        System.out.println("abc".toUpperCase());
        System.out.println("ABC".toLowerCase());

        String str2 = "abc" + "ccc" + "ddd";

        String ss = "aaa".concat("bbb");

        System.out.println(ss);

        String concat = "aaa".concat("bbb").concat("cccc").concat("dddd");
        System.out.println(concat);


    }
}

按要求转换字符

A:案例演示:	需求:把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
public class MyTest8 {
    public static void main(String[] args) {
       /* A:
        案例演示:
        需求:把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)*/
        String str = "aasdfeASFDFasdfeasdfadsfasdf";

        String s = str.substring(0, 1).toUpperCase().concat(str.substring(1).toLowerCase());

        System.out.println(s);
      /*  String one = str.substring(0, 1);
        String s = one.toUpperCase();
        String substring = str.substring(1);
        String s1 = substring.toLowerCase();
        String concat = s.concat(s1);
        System.out.println(concat);
*/


        int a = 20;
        int b = 10;
        //a==b.if
        if (a == b) {

        }
        //"".isEmpty().if
        if ("".isEmpty()) {

        }

        String s2 = "abc";
        //对象名.nn
        if (s2 != null) {

        }
        /*if(s2!=null){

        }*/
        //对象.null
        if (s2 == null) {

        }

    }
}

String类其他功能

A:String的替换功能及案例演示
public String replace(char old,char new) 将指定字符进行互换
public String replace(String old,String new) 将指定字符串进行互换

public class MyTest {
    public static void main(String[] args) {
        //替换功能
        String s = "奥巴马和特朗普是美国总统".replace('奥', '*');
        System.out.println(s);

        String s1 = "奥巴马和特朗普是美国总统".replace("奥巴马", "******");
        System.out.println(s1);

        String s2 = "奥巴马和特朗普是美国总统".replace("奥巴马", "***").replace("特朗普", "***");
        System.out.println(s2);

        String s5 = "                aa   a   aa                       ";
        //去除两端空格
        String trim = s5.trim();
        System.out.println("=====" + trim + "===");


    }
}

B:String的去除字符串量空格

public class MyTest {
    public static void main(String[] args) {
        //1. 去除左端空格
        String s = "   aaaa    ";
        int index = 0;
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (ch == ' ') {
                index++;
                //inndex = i;
            } else {
                break;
            }
        }
        System.out.println(index);
        String s1 = s.substring(index);
        System.out.println(s1);

        System.out.println("==================================");

        //去除右端空格
        int j = 0;
        String s2 = "      abc      ";
        for (int i = s2.length() - 1; i >= 0; i--) {
            char ch = s2.charAt(i);
            if (ch == ' ') {
                j = i;
            } else {
                break;
            }
        }
        System.out.println(j);

        System.out.println(s2.substring(0, j));


    }
}

以及演示

​ public String trim() 去除两端空格

C:String的按照字典比较两个字符串以及案例演示

​ public int compareTo(String str) 会对照ASCII码表从第一个字母进行剑法运算,返回的就是这个减法的结果

如果前面几个字母一样会根据两个字符串的长度进行减法运算返回的就是这个减法的结果

​ 如果两个字符一摸一样,返回的就是0

​ public int compareToTgnoreCase(String str)跟上面一样知识忽略大小写的比较

public class MyTest3 {
    public static void main(String[] args) {
        String s1 = "abcd";
        String s2 = "abc";
        // boolean b = s1.equals(s2);
        //根据字典顺序来比较,如果字典顺序比较不出来,就按照长度比
        int i = s1.compareTo(s2);
        System.out.println(i);

        new String("");


       /*
        compareTo()方法的源码
        public int compareTo (String anotherString){
            int len1 = value.length;
            int len2 = anotherString.value.length;
            int lim = Math.min(len1, len2);
            char v1[] = value;
            char v2[] = anotherString.value;

            int k = 0;
            while (k < lim) {
                char c1 = v1[k];
                char c2 = v2[k];
                if (c1 != c2) {
                    return c1 - c2;
                }
                k++;
            }
            return len1 - len2;
        }*/


        String s3 = "abc";
        String s4 = "ABc";
        System.out.println(s3.compareToIgnoreCase(s4));
    }
}

把数组转换为字符串

A:案例演示
	需求:把数组中的数据按照指定个格式拼接成一个字符串
		举例:
			int[] arr = {1,2,3};	
		拼接结果:
			"[1, 2, 3]"
			
			
public class MyTest {
    public static void main(String[] args) {
      /*  A:
        案例演示
        需求:把数组中的数据按照指定个格式拼接成一个字符串
        举例:
        int[] arr = {1, 2, 3};
        拼接结果:
        "[1, 2, 3]"

        */
        int[] arr = {1, 2, 3, 4, 5, 6, 7};  //"[1, 2, 3,4,5]"
        String str = "[";
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                str += arr[i] + "]";
            } else {
                str += arr[i] + ",";
            }
        }
        System.out.println(str);
    }
}

字符串反转并断点查看

A:案例演示
	需求:把数组中的数据按照指定个格式拼接成一个字符串
		举例:
			int[] arr = {1,2,3};	
		拼接结果:
			"[1, 2, 3]"
			
			
public class MyTest3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一段内容");
        String s = sc.nextLine();
        String str = "";
        for (int length = s.length() - 1; length >= 0; length--) {
            str += s.charAt(length);
        }

        System.out.println(str);
    }
}

			
			
			

在大串中查找小串出现的次数图解

A:画图演示
	需求:统计大串中小串出现的次数
	举例: "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun" 中java出现了5次
	
	
	
	
public class MyTest2 {
    public static void main(String[] args) {
       /* 需求:统计大串中小串出现的次数
        举例:
        "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun" 中java出现了5次*/

        String maxStr = "woaijavawozhjavajavaenaijavawozhejavajavandeaijavawozhendehenaijavaxinbuxinwoaijavagun";
        String minStr = "java";
        int index = maxStr.indexOf(minStr);
        int count = 0;
        while (index != -1) {
            count++;
            maxStr = maxStr.substring(index + minStr.length());
            //再找
            index = maxStr.indexOf(minStr);
        }
        System.out.println(count);
    }
}



public class MyTest4 {
    public static void main(String[] args) {
        String maxStr = "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun";
        int conut = 0;
        if (!maxStr.contains("#")) {
            String s = maxStr.replace("java", "#");
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                if (c == '#') {
                    conut++;
                }
            }
        }

        System.out.println(conut);

        System.out.println("============================================================");
        int length = maxStr.length();
        String java = maxStr.replace("java", "");
        int length1 = java.length();
        int len = (length - length1) / 4;
        System.out.println(len);

    }
}

StringBuffer类的概述

A:StringBuffer类的概述

​ 我们如果对字符串进行拼接,每次凭借,都会创建一个新的String对象,即耗时,有浪费空间。

​ 而StringBuffer就可以解决这个问题

​ 线程可变的可变字符序列

B:简述安全问题

C: String Buffer和String的区别

public class MyTest {
    public static void main(String[] args) {
        //StringBuffer 可变字符序列,长度是可变的。
        // String 一旦定义他的值就不能被改变。
        // StringBuffer 可以认为是一个字符容器,你可以不断的往容器中追加内容。
        // StringBuffer()
        // 构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符。
        StringBuffer sb = new StringBuffer();
        int capacity = sb.capacity(); //获取容量
        System.out.println(capacity);

        sb.append("abcasdfasdfffffffffffffffffffffffffffffffffffffasdfassdf");
        capacity = sb.capacity(); //获取容量
        System.out.println(capacity);
        int length = sb.length(); //获取容器中字符的长度
        System.out.println(length);

        // capacity(); 容量 水杯  500ML
        // length() 长度   水杯装了 200ML

    }
}

StringBuffer类的构造方法

A:StringBuffer的构造方法

​ public StringBuffer() 无参构造方法

​ public StringBuffer(int capacity) 指定容量的字符串的缓冲区对象

​ public StringBuffer(String str) 指定字符串内容的字符串缓冲区对象

B:StringBuffer的方法

​ public int capacity() 返回当前的容量。 理论值

​ public int length() 返回长度 实际值

C:案例构造

​ 构造方法和长度方法的使用

public class MyTest2 {
    public static void main(String[] args) {
        // StringBuffer( int capacity)
        // 构造一个不带字符,但具有指定初始容量的字符串缓冲区。
        StringBuffer buffer = new StringBuffer(100); //可以指定容量
        System.out.println(buffer.capacity());


        // StringBuffer(String str)
        // 构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。

        StringBuffer sb = new StringBuffer("hello");


    }
}

StringBuffer的添加功能

A:StringBuffer的添加功能

​ public StringBuffer append(String str): 可以把任意类型的数据添加单字符串的缓冲区里面,并返回到字符串缓冲区本身

public class MyTest {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();

        //往字符串缓冲区中追加内容,返回的还是原来的那个对象
        StringBuffer sb2 = sb.append("abc");

        System.out.println(sb == sb2); //true
        //因为我们调用完append()方法后,返回的还是那个对象,所以我就可以链式编程。
        sb.append(100).append(true).append(3.14);

        //StringBuffer 重写了toString方法,会把他容器中的内容转换成字符串
        String s = sb.toString();
        System.out.println(s);

    }
}

​ public StringBuffer insert(int offest,String str): 在指定位置把任意类型的数据插入到字符串的缓冲区 里面,并返回给字符串的缓冲区本身


B:案例演示

​ StringBuffer的添加功能

public class MyTest3 {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append("aaa").append("bbb");
        //可以在指定位置,追加内容,返回的还是原来的那个容器
        StringBuffer sb2 = sb.insert(0, "0000000");
        System.out.println(sb == sb2);
        System.out.println(sb.toString());
    }
}

StringBuffer的删除功能

A:StringBuffer的删除功能

​ public StringBuffer deleteCharAt(int index):删除指定位置的字符,并返回本身

​ public StringBuffer delete (int start,int end):删除从指定位置开始到指定位置结束的内容,并返回该本身(含头不含尾)

B:案例演示

​ StringBuffer的删除功能

public class MyTest4 {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append("西部开源教育科技有限公司");
        //根据索引一次删除容器中的一个字符,返回的还是容器本身
        sb.deleteCharAt(0);
        System.out.println(sb.toString());
        //可以根据起始索引和终止索引,删除容器中的一段内容,返回的还是容器本身
        sb.delete(0, 3); //含头不含尾
        System.out.println(sb.toString());

    }
}

StringBuffer的替换和反转功能

A:StringBuffer的替换功能

​ public StringBuffer replace(int start,int end,String str):从start 开始到end用str替换

B:StringBuffer的反转功能

​ public StringBuffer reversr(): 字符串反转

C:案例演示

​ StringBuffer的替换和反转功能

public class MyTest {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append("西部开源教育科技有限公司");
        //根据起始索引和终止索引,替换容器中的内容,返回的还是容器本身
        sb.replace(0, 4, "天天向上"); //含头不含尾
        System.out.println(sb.toString());

        //反转容器中的内容,返回的还是容器本身
        sb.reverse();
        System.out.println(sb.toString());
    }
}

从头查找该字符串,在容器中第一次出现的索引,如果找不到就返回-1

​ int indexof(String str)

从指定索引处开始查找字符串第一次出现的索引,如果找不到就返回-1

​ int indexof (String str, int fromIndex)

从后往前找
int lastIndexOf (String str)

int lastIndexOf (String str,int fromIndex)

StringBuffer的截取功能

A:Stringbuffer的截取功能

​ public String substring(int start): 从指定位置截取到末尾
​ public String substring(int start,int end): 截取从指定位置开始到结束位置,包括开始位置,不包括结束位置

B:注意事项:

​ 注意:在StringBuffer中substring返回值类型不再是StringBuffer本身

C:案例演示

​ StringBuffer的截取功能以及之一事项

public class MyTest2 {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append("西部开源教育科技有限公司");
        String s = sb.substring(0, 4);
        System.out.println(s);

    }
}

StringBuffer和String的相互转换

A:String---------StringBuffer

​ a:通过构造方法

​ b:通过append()方法

B:StringBuffer---------String

​ a:使用substring方法

​ b:透过构造方法

​ c:通过toString()方法

C:案例演示

​ StringBuffer和String的相互转化

public class MyTests {
    public static void main(String[] args) {
        //String
        // StringBuffer

        //String----StringBuffer
        String str = "abc";
        StringBuffer sb = new StringBuffer(str);
        StringBuffer sb2 = new StringBuffer().append(str);


        //StringBuffer---String
        StringBuffer sb3 = new StringBuffer("aaaa");
        String s = sb3.toString();
        String s2 = sb3.substring(0);

        String s1 = new String(sb3);

    }
}

把数组转换为字符串

A:案例演示
需求:把数组中的数据按照指定个格式拼接成一个字符串
举例:
int[] arr = {1,2,3};
输出结果:
“[1, 2, 3]”
用StringBuffer的功能实现

public class MyTest2 {
    public static void main(String[] args) {
      /*  A:
        案例演示
        需求:把数组中的数据按照指定个格式拼接成一个字符串
        举例:
        int[] arr = {1, 2, 3};
        输出结果:
        "[1, 2, 3]"*/

        int[] arr = {1, 2, 3, 4, 5, 9};
        StringBuffer sb = new StringBuffer("{");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                sb.append(arr[i]).append("}");
            } else {
                sb.append(arr[i]).append(",");
            }
        }
        String s = sb.toString();
        System.out.println(s);

    }
}

字符串的反转

A:案例演示
需求:把字符串反转
举例:键盘录入"abc"
输出结果:“cba”
用StringBuffer的功能实现

public class MyTest3 {
    public static void main(String[] args) {
        // A:
        // 案例演示
        // 需求:把字符串反转
        // 举例:键盘录入 "abc"
        // 输出结果:"cba"
        //用StringBuffer的功能实现
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一段内容");
        String s = scanner.nextLine();
        String s1 = new StringBuffer(s).reverse().toString();
        System.out.println(s1);
    }
}

StringBuffer和StringBuffer的区别

A:StringBuilder的概述
通过查看API了解一下StringBuilder类
B:面试题
String,StringBuffer,StringBuilder的区别

public class MyTest4 {
    public static void main(String[] args) {
        //StringBuffer :线程安全的可变字符序列,线程安全效率低一些。


        /*一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。
        该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比
        StringBuffer 要快。*/
        //StringBuilder :线程不安全的可变字符序列。线程不安全效率高一些。


    }
}

String和StringBuffer分别作为参数传递

A:形式参数问题

​ String作为参数传递 String虽然是引用类型,但是他是一个常量,所以在做传递的时候,完全可以将其看成基本类型数据传递,String输入类型输入传递

​ StringBuffer作为参数传递

B:案例演示

​ String和StringBuffer分别作为参数传递问题

public class MyTest {
    public static void main(String[] args) {
        //引用类型作为参数传递,属于引用传递,传递的是地址值,形参的改变会影响实参。
        //String类比较特殊,他作为参数传递,属于值传递,传递的是字符串的值,形参的改变不影响实参
        //基本类型作文参数传递,属于值传递,传递的是值,形参的改变不影响实参。
        String str = "hello";
        test(str);
        System.out.println(str); //2.hello
        StringBuffer sb = new StringBuffer("abc");
        test(sb);
        System.out.println(sb); //3.bbbcba
    }

    private static void test(String str) {
        str += "wolrd";
        System.out.println(str); //1.helloworld
    }

    private static void test(StringBuffer sb) {
        sb.append("bbb").reverse();
    }
}

补充:StringJoiner

StringJoiner(charSequence delimiter)

构建一个字符容器,指定分割符

StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix)

构建一个字符容器,指定分割符,前缀,后缀

StringJoiner add(CharSequence newElement)

增加一份CharSequence的值给StringJoiner的值的下一个元素

int length()

返回StringJoiner的String表示长度

String toString() 把容器中的数据以字符串返回

数据高级冒泡排序原理图解

A:画图演示
需求:
数组元素:{24, 69, 80, 57, 13}
请对数组元素进行排序。

B:冒泡排序原理
相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处

public class MyTest2 {
    public static void main(String[] args) {
         /*  A:
        案例演示
        需求:把数组中的数据按照指定个格式拼接成一个字符串
        举例:
        int[] arr = {1, 2, 3};
        输出结果:
        "[1, 2, 3]"*/

        int[] arr = {1, 2, 3, 4, 5, 9};
        StringJoiner joiner = new StringJoiner(",", "[", "]");
        for (int i = 0; i < arr.length; i++) {
            joiner.add(arr[i] + "");
        }
        String s = joiner.toString();
        System.out.println(s);


        StringJoiner joiner1 = new StringJoiner("-", "[", "]");
        String s1 = joiner1.add("张三").add("李四").add("王五").toString();
        System.out.println(s1);
    }
}

数组高级选择排序原理图解

A:画图演示
需求:
数组元素:{24, 69, 80, 57, 13}
请对数组元素进行排序。

B:选择排序原理
从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处

public class MyTest {
    public static void main(String[] args) {
        //选择排序:每次拿一个元素,跟他后面的元素挨个比较,小的往前放,经过一轮比较,最小的元素就会出现在最前面,如此往复,经过几轮后,就会排序好。
        /*数组元素:{
            24, 69, 80, 57, 13
        }*/

        int[] arr = {24, 69, 80, 57, 13, 2, 0, 3, 8};
        //tuiDao(arr);

        for (int index = 0; index < arr.length - 1; index++) {
            for (int i = 1 + index; i < arr.length; i++) {
                if (arr[i] < arr[index]) {
                    int t = arr[i];
                    arr[i] = arr[index];
                    arr[index] = t;
                }
            }
        }

        System.out.println(Arrays.toString(arr));

    }

    private static void tuiDao(int[] arr) {
        //第一轮:从0索引处开始,挨个跟他后面的元素比较
        int index = 0;
        for (int i = 0 + 1; i < arr.length; i++) {
            if (arr[i] < arr[index]) {
                int t = arr[i];
                arr[i] = arr[index];
                arr[index] = t;
            }
        }

        System.out.println(Arrays.toString(arr));

        //第二轮:从1索引处开始

        index = 1;
        for (int i = 0 + 1 + 1; i < arr.length; i++) {
            if (arr[i] < arr[index]) {
                int t = arr[i];
                arr[i] = arr[index];
                arr[index] = t;
            }
        }

        System.out.println(Arrays.toString(arr));
        //第三轮:从2索引处开始
        index = 2;
        for (int i = 0 + 1 + 1 + 1; i < arr.length; i++) {
            if (arr[i] < arr[index]) {
                int t = arr[i];
                arr[i] = arr[index];
                arr[index] = t;
            }
        }

        System.out.println(Arrays.toString(arr));

        //第四轮:从3索引处开始
        index = 3;
        for (int i = 0 + 1 + 1 + 1 + 1; i < arr.length; i++) {
            if (arr[i] < arr[index]) {
                int t = arr[i];
                arr[i] = arr[index];
                arr[index] = t;
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

二分查找

A:画图演示
B:二分查找:前提数组元素必须有序
C:二分查找的思想:每一次都查中间的那个元素,比较大小就能减少一半的元素。

public class MyTest {
    public static void main(String[] args) {
        //查找该元素第一次出现的索引
        int[] arr = {10, 20, 30, 50, 50, 50, 50, 60, 70, 80, 90, 100};
        //基本查找
        // int index = getIndex(arr, 24);
        //  System.out.println(index);

        //二分查找:前提是数组元素有序
        //二分查找,他不是找该元素第一个出现的索引

        int index = getIndex2(arr, 50);
        System.out.println(index);


    }

    //二分查找
    private static int getIndex2(int[] arr, int ele) {
        //定义三个变量
        int minIndex = 0;
        int maxIndex = arr.length - 1;
        int centerIndex = (minIndex + maxIndex) / 2;
        while (minIndex <= maxIndex) {
            if (ele == arr[centerIndex]) {
                return centerIndex;
            } else if (ele > arr[centerIndex]) {
                minIndex = centerIndex + 1;
            } else if (ele < arr[centerIndex]) {
                maxIndex = centerIndex - 1;
            }
            //重新计算中间索引
            centerIndex = (minIndex + maxIndex) / 2;
        }

        return -1;
    }

    private static int getIndex(int[] arr, int ele) {
        for (int i = 0; i < arr.length; i++) {
            if (ele == arr[i]) {
                return i;
            }
        }
        return -1;
    }
}

Arrays类的概述和方法使用

A:Arrays类概述

​ 针对数组进行操作的工具类。

​ 提供了排序,查找等功能

B:成员方法

​ public static String toString(int[] a)

​ public static void sort (int[] a)

​ public static int binarySeach(int[] a,int key)

​ static boolean equals(int[] a,int[] a2)比较两个数组的元素,是否一样

​ static int[] copyof(int[] original, int newlength) 复制旧数组的元素到一个新的数组中,新的数组长度是newlength从0开始赋值到旧数组

​ static int[] copyOfRange(int[] original, int from, int to) 复制旧数组中的指定范围间的几个元素到新数组中

案例演示:

​ 通过Arrays类的功能来进行排序和查找

    public static void main(String[] args) {
        int[] arr = {10, 20, 30};
        int[] arr2 = {10, 20, 20};
        boolean equals = Arrays.equals(arr, arr2);
        System.out.println(equals);

        /*
        *
        *       public static boolean equals(int[] a, int[] a2) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;

        int length = a.length;
        if (a2.length != length)
            return false;

        for (int i=0; i<length; i++)
            if (a[i] != a2[i])
                return false;

        return true;
    }
        *
        *
        * */

    }
}




public class MyTest4 {
    public static void main(String[] args) {
       /* static int[] copyOf ( int[] original, int newLength)复制旧数组中的元素到一个新的数组中,新的数组长度是newLength 从0开始复制旧数组
        static int[] copyOfRange ( int[] original, int from, int to)复制旧数组中的指定范围间的几个元素到新数组中*/


        int[] arr = {10, 20, 30, 50, 58880, 990, 5088, 60, 70, 80, 90, 100};
        int[] ints = Arrays.copyOf(arr, 3);
        System.out.println(Arrays.toString(ints));

        //通过指定起始索引和终止索引,从旧数组中拷贝一部分元素到新数组中
        int[] ints1 = Arrays.copyOfRange(arr, 3, 5); //含头不含尾

        System.out.println(Arrays.toString(ints1));


    }
}


Arrays类的源码解析

A:源码解析
public static String toString(int[] a)
B:源码解析
public static int binarySearch(int[] a,int key)

A:源码解析
	public static String toString(int[] a)
B:源码解析
	public static int binarySearch(int[] a,int key)

基本类型包装类的概述

A:需求

​ 1。将100转换为二进制,八进制,十六进制

​ 2。判断一个数是否int的范围内

B:为什么会有基本类型包装类

​ 为了对基本类型进行更多的操作,更方便的操作,Java就针对没一种基本类型提供了对应的类类型。

C:常用的操作:常用的操作之一;用于基本类型与字符串之间的转换

D:基本类型和包装类的对应

byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

Integer的概述和构造方法

A:Integer类概述

​ JDK提供的API,查看Integer的说明

​ Integer类再对象包装了一个基本类型int的值

​ 该类提供了多个方法,能在int类型和String类型之间互相转化

​ 还提供了处理int类型时类型非常有用的其他一些常量和方法

B:构造方法

public Integer(int value)
public Integer(String s)  //要个一个字面上是数字的字符串,如果不是就会报错	

C:案例

​ 使用构造方法创建对象

public class MyTest {
    public static void main(String[] args) {
        // a:
        // 将100转换成二进制, 八进制, 十六进制
        // b:
        // 判断一个数是否在int的范围内

        //int num=100;

        //Java为了我们方便的操作这些基本数据类型,给我们提供了基本数据类型所对应的包装类
        /*
         *  byte  ------  Byte
         *  short------ Short

         *  int  ----- Integer
         *   long -----  Long
         *   char ---- Character
         *    boolean  -----Boolean
         *    float -----  Float
         *   double ---- Double
         *
         *
         *
         *
         * */


        int num = 100;
        String s = Integer.toBinaryString(num);
        String s1 = Integer.toOctalString(num);
        String s2 = Integer.toHexString(num);
        System.out.println(s);
        System.out.println(s1);
        System.out.println(s2);

        int maxValue = Integer.MAX_VALUE;
        int minValue = Integer.MIN_VALUE;
        System.out.println(maxValue);
        System.out.println(minValue);

        // Long.MAX_VALUE
        //         Long.MIN_VALUE

    }

String和int类型的相互转换

A:int—String

​ 1.和""进行拼接

​ 2.public static String valueof(int i)

​ 3.int----Integer–String

​ 4.public static String toString(int i)

B:String—int

​ 1.String–Integer–intValue()

​ 2.public static int parseInt(String s)

C:案例演示

​ String和int类型之间的转换

public class MyTest2 {
    public static void main(String[] args) {
        // Integer
        // Integer( int value)
        // 构造一个新分配的 Integer 对象,它表示指定的 int 值。
        // Integer(String s)
        // 构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。

        Integer integer = new Integer(100);
        //NumberFormatException 数字格式化错误
        //要的字符串是字面上是个数字
        Integer integer2 = new Integer("100");


    }
}


public class MyTest3 {
    public static void main(String[] args) {
        int num = 100;
        //100-----"100"
        //方式1:拼接空串
        String str = num + "";
        String s2 = String.valueOf(num);

        String s = new Integer(num).toString();
        System.out.println(s);

        //"100"----100

        String str2 = "100";
        //推荐的方式
        int i = Integer.parseInt(str2); //NumberFormatException: For input string: "100a"
        System.out.println(i);
        Integer integer = new Integer(str2);
        int i1 = integer.intValue();
        System.out.println(i1);
    }
}



JDK1.5的新特性自动装箱和拆箱

A:JDK5的新特性

​ 自动装箱:把基本类型转为包装类类型

​ 自动拆箱:把包装类型转为基本类型

B:案例演示

​ JDK的新特性自动装箱和拆箱

​ Integer ii=100;

​ ii+=200;

public class MyTest {
    public static void main(String[] args) {
        //JDK1.5
        //自动拆箱:将包装类型自动转换为他对应的基本数据类型。
        //自动装箱:将基本数据类型,自动转换为对应的包装类型。

        int num = 100;

        Integer n = num; //自动装箱
        Integer n2 = new Integer(num);


        Integer a = new Integer(2);
        Integer b = new Integer(3);

        //自动拆箱:将包装类型自动转换为他对应的基本数据类型。
        System.out.println(a + b);


    }
}

public class MyTest3 {
    public static void main(String[] args) {
        //手动装箱
        int num = 0;
        Integer integer = new Integer(num);
        //手动装箱
        //Integer n=20;
        Integer integer1 = Integer.valueOf(num);

        Integer integer2 = Integer.valueOf("200");

        //手动拆箱

        Integer a = new Integer(2);

        Integer b = new Integer(3);
        //手动拆箱
        int i = a.intValue();
        int i1 = b.intValue();
        System.out.println(i + i1);

        int r = a + b; //自动拆箱
        System.out.println(a + b);


    }
}





C:注意事项

​ 再使用的时候,Ingeter x=null;代码就会出现

NullPointerException。

​ 建议先判断是否时null,然后再使用。

Integer面试题


public class MyTest4 {
    public static void main(String[] args) {
        Integer i1 = new Integer(127);
        Integer i2 = new Integer(127);

        System.out.println(i1 == i2); //false
        //Integer他重写了equals方法,比较的是他包装的值是否相同
        System.out.println(i1.equals(i2)); //true

        System.out.println("-----------");

        Integer i3 = new Integer(128);
        Integer i4 = new Integer(128);
        System.out.println(i3 == i4); //false
        System.out.println(i3.equals(i4)); //true

        System.out.println("-----------");

        Integer i5 = 128; //new Integer(128);
        Integer i6 = 128;
        System.out.println(i5 == i6); //false
        System.out.println(i5.equals(i6)); //true

        System.out.println("-----------");

        Integer i7 = 127;
        Integer i8 = 127;
        System.out.println(i7 == i8); //true
        System.out.println(i7.equals(i8)); //true

        //Integer 也重写了toString()方法,把他包装的值,转换成字符串
        String s = i7.toString();
        System.out.println(s);


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值