[细碎的Java1.0]EDG我RNG 三巨头

111 

/*
  Java的应用领域:安卓的应用程序使用Java语言编写
  什么是程序?计算机执行某些操作或解决某个问题而编写一系列有序指令的集合
  Java的诞生:1995年Sun公司开发了java ;2009年Oracle收购了Sun公司 ; 其中2004年的java5.0和2014年的java8.0更新力度最大
   因为有JVM(虚拟的计算机),同一个Java程序在三个不同的操作系统(Windows/Linux/Mac)都可以可以执行
   java特性:面向对象opp ,跨平台的,Java语言是解释性语言,编译后的代码,不能直接被机器执行,需要解释器来执行。编译性语言(C/C++),可以直接被机器执行
   Java SE标准版  Java EE企业版  Java ME小型版
   JDK(java开发工具包)=JRE(运行环境)+开发工具类  JRE=JVM+Java SE标准类库
   1+1在二进制中不等于2,一个小目标8个0,bit比特位  Byte字节  KB  MB  GB   TPEZ  带tp的ez   /正斜杠   \反斜杠

 */


public class HelloWorld {//表示HelloWorld是一个路,是一个public共有的类  {}表示一个类的开始和结束
    public static void main(String[] args){//主方法程序的入口 {}表示一个方法的开始和结束
        System.out.println("HelloWorld");//输出语句   ;表示语句的结束
    }
}
class HelloWorldOne{//HelloWorldOne是一个类,编译后每一个类都会对应一个.class
    public static void main(String[] args){
        System.out.println("One类执行");
    }
}
//通过运行工具java.c对字节码文件进行执行,本质将.class装载到JVM机运行 源文件基本组成部分是类(class)
//一个源文件最多只能有一个public类,其他类不限个数,也可以将main方法写在非public类中,然后指定运行非public类这样入口方法就是非public的main方法
//工作需求/技术控--->传统技术能解决,但不完美/不能解决----->引领我们学习新的知识点----->学习新技术或者知识点一定不要考虑细节---->快速入门----->开始研究技术注意事项,永无止境

222 

/*public class Object {
    //成员变量  访问修饰符(控制属性的访问范围 public proctected 默认 private) 属性有默认值整形0,浮点类型0.0,字符类型、u0000,boolean false,String null
    //Java内存的结构分析 栈(基本数据类型局部变量),堆(存放对象,new出来的东西),方法区(常量池常量,字符串和类的加载信息),寄存器(和CPU相关),本地方法栈(与操作系统相关)
  //类的加载信息只会加载一次 当程序执行到方法时,就会开辟一个独立的栈空间
    //成员方法的好处:提高代码复用性;将细节封装起来,然后供其他用户调用即可
    public static void main(String[] args) {
        *//*Compute one=new Compute();//跨类方法需要通过创建对象调用
        int array1[]=one.numberCompute(2,5);
        System.out.println("和"+array1[0]);
        System.out.println("差"+array1[1]);*//*

        judgementNumber one=new judgementNumber();
        if(one.is(5)){
            System.out.println("偶数");
        }else{
            System.out.println("奇数");
        }
    }
}
class myMain{
    public void print(int number){
        System.out.println("要输出的数字是"+number);
    }
    public void sayOk(){
        print(10);//同一类中直接调用
        System.out.println("我很OK");
    }
}
*//*class Compute{
    //一个方法只能有一个返回值,要传递多个返回值,需要返回数组
    //方法不能嵌套定义
    public  int[] numberCompute(int number1,int number2){
        int array[]=new int[2];
        array[0]=number1+number2;
        array[1]=number1-number2;
        return array;
    }
}*//*
class judgementNumber{
    public boolean is(int number){
        return number%2==0;
    }
}*/

//成员方法的传参机制:基本数据类型(值拷贝),引用数据类型(址拷贝)
/*public class Object {

    public static void main(String[] args) {
        //递归执行一个方法时,会创建一个独立的栈空间;如果使用的是引用数据类型,就会共享该引用类型的数据

       *//* System.out.println(Question1(5));
        System.out.println("第一天有"+peach(1)+"桃子");

        //3.迷宫问题
        int[][] map=new int[8][7];//迷宫用二维数组表示
        for (int i = 0; i < 7; i++) {
            map[0][i]=1;
            map[7][i]=1;
        }
        for (int i = 0; i < 7; i++) {
            map[i][0]=1;
            map[i][6]=1;
        }
        map[3][1]=1;map[3][2]=1;
        map[2][2]=1;//测试回溯现象
        findWay(map,1,1);
        System.out.println("=====路径=====");
        for (int i = 0; i < map.length; i++) {
            for(int j=0;j<map[i].length;j++){
                System.out.print(map[i][j]+" ");
            }
            System.out.println();
        }*//*

        move(3,'a','b','c');


        *//*
        八皇后在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,
        即:任意两个皇后不能处于同一行、同一列或同一斜线上,问有多少种摆法
        这里用一维数组存放数据就可以了,这里一维数组中的值存放的是皇后的列坐标,
	    因为规定皇后是不能摆放在同一行,所以每一行只有一个皇后 ; 一维数组 array
	    的第一个值就是 棋盘第一行皇后的列坐标值,第二个值就是皇后在棋盘第二行的列坐标值
         *//*


    }
    //1.斐波那契数列问题
    public static int Question1(int number){
        if(number>=1){
            if(number==1||number==2){
                return 1;
            }else{
                return Question1(number-1)+Question1(number-2);
            }
        }else{
            System.out.println("要求number>=1的整数");
            return -1;
        }
    }

    //2.猴子吃桃问题 每天猴子吃其中一半,在多吃一个,第十天只有一个桃子,问最初有多少个桃子
    public static int peach(int day){
        if(day==10){
            return 1;
        }
        else if(day>=1&&day<=9){
            return (peach(day+1)+1)*2;
        }else{
            System.out.println("数据不合法,返回-1");
            return -1;
        }
    }
    //3.出迷宫问题
    public static boolean findWay(int map[][],int row,int col){
        *//*findWay找迷宫的路径,找到返回true,找不到false
          row 和col表示我现在的位置
          map数组各个值的含义 0表示可以走 1表示障碍物 2表示可以走 3表示可以走,但走不通
          走路策略下->右->上->左
        *//*
        if(map[6][5]==2){
            return true;
        }
        else{
            if(map[row][col]==0){//位置是0,可以走
                map[row][col]=2;//假设可以走通
                if(findWay(map,row+1,col)){//下
                    return true;
                }else if(findWay(map,row,col+1)){//右
                    return true;
                }else if(findWay(map,row-1,col)){//上
                    return true;
                }else if(findWay(map,row,col-1)){//左
                    return true;
                }else{
                    map[row][col]=3;
                    return false;
            }
            }else{
                return false;
            }
        }

    }

    //4.汉诺塔问题
    public static void move(int number,char one,char two,char three){
        if(number==1){
            System.out.println(one+"->"+three);
        }else{
            //先移动所有盘子到two
            move(number-1,one,three,two);//多个盘子先看成两个,最下面和上面的盘子
            //再把最下面盘子放到three
            System.out.println(one+"->"+three);
            move(number-1,two,one,three);
        }
    }

}*/

//方法重载(减轻起名问题和记名的麻烦)方法名相同,参数类型个数或顺序至少一个不同,返回类型和参数名无要求
/*public class Object {
    public static void main(String[] args){
        int array[]={1,2,3};
        //可变参数的实参可以为数组 可变参数的本质就是数组
        //System.out.println(sum(array));
        System.out.println(out("开炮",5,6));
    }
    *//*public static int sum(int... numbers){//int...表示可变参数,类型int
        //一个形参列表只能出现一个可变参数
        System.out.println("长度="+numbers.length);
        return 0;
    }*//*
    public static String out(String one,int...numbers){
        //可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数要放到最后
        int sumNumber=0;
        for(int i=0;i<numbers.length;i++){
            sumNumber+=numbers[i];
        }
        return "意大利炮发射"+sumNumber+"次";
    }
}*/
//不给全局变量赋值也可以直接使用因为有默认值;局部变量必须赋值
//属性(成员变量)和局部变量可以重名,访问时遵循就近原则 属性伴随方法,局部伴随代码块 局部变量不可以加修饰符,属性可以

/*public class Object {
    public static void main(String[] args){
        *//*
       前面创建人类对象时,先把对象创建好,再给他的年龄和姓名等属性赋值;
       如果现在创建人类对象,就直接指定这个对象的年龄和姓名,这事就使用到了构造方法/构造器
       他的主要作用是完成对新对象的初始化;在创建对象时,系统自动调用该类的构造器完成对对象的初始化,并不是创建对象

         *//*
        *//*Person one=new Person();
        System.out.println("main->"+one.hashCode());//将对象的内部地址转化成一个整数*//*

        //this访问成员方法的语法  this.方法名(参数列表)
        //访问构造方法语句   this(参数列表) 注意只能在构造器中使用(只能在构造器中访问另一个构造器)
       *//* Person one=new Person("阿伟",20);
        Person two=new Person("奥特曼",18);
        System.out.println(one.compare(two));*//*
        Judge one=new Judge();
        //double array[]=null;//引用类型可以赋null
        double array[]={1.11,1.21,1.31};
        if(one.max(array)!=null){
            System.out.println("array的最大值"+one.max(array));
        }else{
            System.out.println("输入有误");
        }
        //简单的说:那个对象调用,this就代表那个对象

    }
}
*//*class Person{//方法名和类名相同
   *//**//* String name;
    int age=18;//显示初始化
    //构造器的修饰符可以默认
    *//**//**//**//*public Person(String pName,int pAge){//没有返回值
        System.out.println("构造器被调用~完成对象的属性初始化");
        name=pName;
        age=pAge;
    }//javap反汇编*//**//**//**//*
    public Person(){//无参构造器  构造器可以重载 不写系统也会自动给
    this("龙" ,1998);//this访问构造方法时 必须放置第一条语句
        System.out.println("无参");
    }
    public Person(String name,int age){
        this.name=name;
        this.age=age;
        System.out.println("name age->"+hashCode());
        System.out.println("有参");
    }*//**//*

    String name;
    int age;
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public boolean compare(Person one){
        return this.name.equals(one.name)&&this.age==one.age;
    }
}*//*

class Judge{
    public Double max(double[] array){
        if(array!=null&&array.length>0) {//先完成正常任务,在考虑代码的健壮性
            double max = array[0];//先假设第一个元素就是最大值
            for (int i = 0; i < array.length; i++) {
                if (max < array[i]) {
                    max = array[i];
                }
            }
            return max;
        }else{
            return null;//返回值double不能以null返回,但Double可以
        }
    }
}*/

/*  out--->存放编译后的  .class文件  src--->源码文件  .java
  补全代码 alt + /
  快速格式化代码 ctrl + alt + L
  生成构造器 alt + insert[提高开发效率]
  查看当前类的层级关系 ctrl + H[学习继承很有用]
  自动分配变量名  .var

  查看那些模板快捷键
  File->Settings->Editor->Live templates模板(sout,main等)可以高效的完成开发,提高速度

  包的作用:当类很多时,可以更好地管理类  package(关键字) com.test(包含)  package声明当前类所在包,需要放在类最上面,一个类只能有一个package
  包的本质 创建不同文件夹存放类文件
  包的命名规则:数字,字母,下划线和小圆点(.),数子不能开头,不能是关键字和保留字
  包的命名规范: 一般小写字母+小圆点 com.公司名.项目名.业务模块名  com.tengxun.game.hero
  java.lang.*    lang是基本包,默认引入
  java.util.*(表示包下所有类都引入)    系统提供的工具包  java.util.Scanner表示只会引入java.util包下的Scanner
  java.net.*     网络包(网络开发)
  java.awt.*     java的界面开发
 */
/*
访问修饰符:(访问权限)(修饰属性,成员方法和类)(只有public和默认才能修饰类)
public 对外公开 (同类 同包 子类 不同包)
protected  对子类和同一个包的类公开 (同类 同包 子类 )
默认 同一个包的类公开  (同类 同包 )
private 只能类本身可以访问,不对外公开  (同类 )
 */

//面向对象的三大特征:封装(隐藏实现细节)  继承  多态
/*class Person{
    //将属性进行私有化
    public String name;
    private int age;
    private double salary;

    public Person() {
    }

    public Person(String name, int age, double salary) {
        setName(name);//把set写在构造器中,
        setAge(age);
        setSalary(salary);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {//提供一个公共的set方法,用于对属性判断并赋值
        if(name.length()>=2&&name.length()<=6){

            this.name = name;
        }else{
            System.out.println("名字长度超出范围,无法显示,抱歉,将默认为无名");
            this.name="无名";
        }
    }

    public int getAge() {//提供一个公共的get方法,用于获取属性的值
        return age;
    }

    public void setAge(int age) {
        if(age>=0&&age<=100){

            this.age = age;
        }else{
            System.out.println("年龄超出正常范围,无法显示,抱歉,将默认为18");
            this.age=18;
        }
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}
public class Object {
    public static void main(String[] args) {
        Person one=new Person("阿伟",2000,900);
        System.out.println("姓名"+one.getName()+"年龄"+one.getAge()+"工资"+ one.getSalary());
    }
}*/

/*继承(提高了代码的复用性和维护性)  class 子类 extends 父类{}  父类又叫超类,基类     子类又叫派生类
细节1:父类中的私有属性不能在子类直接访问,要通过公共方法去访问 ,属性(public int getName(){}等)/成员方法(公共调用private的方法)
    2.创建子类对象,先调用父类的构造器完成初始化,若父类没有提供无参构造器,则必须在子类中指定使用父类那个构造器完成对父类初始化操作;否则编译不通过
    调用父类无参构造器,要么什么都不写,要么写super();  //super()和this()必须放在第一行,因此这两个方法不能共存在一个构造器中
    3.java所有类都是Object的子类  父类构造器的调用一直到Object(只是这个顶级父类什么都不打印罢了);如果要查找的信息子类没有,则向上查找,如果到Object还没有,则报错
    4.java子类父类继承是单继承(子类只能有一个父类)
    5.不能滥用继承,必须要满足逻辑关系  Music extends Person 音乐继承人???  Cat extends Animal 猫继承动物 yes yes yes
 */

/*
方法的重写:子类的参数,方法名称和父类的参数方法名称一样;子类的返回类型和父类的返回类型一样,或者是父类返回类型的子类;子类的方法不能缩小父类方法的访问权限

重写和重载的区别:1.发生范围(父子类,本类) 2.方法名(必须一样) 3.形参列表(相同,类型个数顺序至少有一个不同) 4.返回类型(子类返回类型是父类的子类或相同,无要求) 5.修饰符(子类的访问方法大于等于父类,无要求)
 */

/*多态(提高代码的复用性和维护性) 多态是建立在封装和继承基础之上的
多态的具体体现:1.方法的多态(重写和重载--根据对相不一样,调用的方法也不一样)
              2.对象的多态(Person one = new xiaoMing();举例) //假如xiaoMing是Person的子类对象
              =左边是编译类型(Person);等号右边是运行类型(xiaoMing);
              一个对象的编译类型和运行类型可以不一样,运行类型是可以变化的(也可以new Person();)
              编译类型在定义对象时,就确定了,不能改变(就相当于人一生下来就有亲生父亲,你可以认干爹,但不能改变亲生父亲)

多态的前提是:两个对象存在继承关系  本质:父类的引用指向子类对象(向上转型)  可以调用父类的所有成员(特殊成员除外)(能调用那些类型是由编译类型决定的),最终运行效果看右边的运行类型

            如果要调用父类的特殊成员需要向下转型  xiaoMing one = new (xiaoMing)Person;(编译是xiaoMing,运行用了强转也是xiaoMing)  只能强转父类的引用,不能强转父类的对象;要求父类的引用必须指向当前目标类型的对象,才可以调用子类的所有成员
            属性没有重写之说,属性的值看编译类型
            instanceOf比较操作符,用于判断对象类型是否为某个类的类型或某个类的子类型

java的动态绑定机制:1.当调用对象方法时,该方法会和该对象的内存地址/运行类型绑定  2.当调用对象属性时,没有动态绑定机制,那里声明,那里使用

 //多态数组:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型 Person[] person = new Person[3]; 遍历的时候person.length

   ==基本类型判断值,引用类型判断地址  equals只能判断基本类型(默认判断地址是否相等,子类往往重写该方法,用于判断内容是否相等)
   equals(Object类的方法,Java类都可以使用equals)
 */

333 

//Java常见的转义字符
/*public class One {
    public static void main(String[] args) {
        System.out.println("你好\t北京");
        System.out.println("你好\n上海");//   \n换行
        System.out.println("D:\\新建文件夹 (11)\\Start"); //  \\两个转义一个\
        System.out.println("我说:\"你要好好学Java\""); //  转义一个"
        System.out.println("我说:\'你要好好学Java\'");//  转义一个'
        System.out.println("你好你好\r成都");//回车和换行不一样
        //选中Tab整体右移   Shift+Tab整体左移
    }
}*/
//多行注释不允许嵌套

/**
 * @author 阿伟
 * @version 5.0
 */
//文档注释可以被Javadoc所解析,生成一套以网页文件形式体现的该程序的文档 javadoc -d 文件夹名 -xx -yy One.java

/*
DOS(磁盘操作系统) 相对路径:从当前目录开始定位,形成一个路径  绝对路径:从顶级目录开始定位
 dir查看当前目录内容  cd进入其他目录  cd ..返回上一级  cd\切换根目录 tree查看指定目录所有子集目录 清屏cls 退出exit md创建文件 rd删除文件 move剪切文件 echo输入内容到文件 copy拷贝文件 del删除文件
 坏境变量的作用是为了在dos的任意目录,可以使用java和javac命令
 */
//变(变化)量(值)
/*
public class One{
    //加法(+)当左右两别都是数值型,做加法运算;当左右两边一方为字符串,则做拼接运算
    public static void main(String[] args){
        System.out.println(100+3);
        System.out.println("Hello"+100+3);//打印结果Hello1003
    }
}*/

/*
Java数据类型
数据类型:基本数据类型(整数类型byte,short,int21个亿,long,浮点类型double,float,字符类型char(2字节),布尔类型(1字节)boolean)
引用数据类型(类,数组,接口)
        java中默认整数类型是int(使用long类型要加L),浮点类型是double(使用float要加F)
        浮点数可能只是一个近似值并非精确值(1/3)double 和 float区别
        数据的范围与字节数无关,float(四个字节)比long(八个字节)数据范围更广泛
 */

/*public class One{
    public static void main(String[] args){
        System.out.println(.512);//正确  必须加小数点
        System.out.println(5.12E-1);//科学计数法表示
        System.out.println(5.12E1);//科学计数法表示
        //单精度和双精度的区别
        System.out.println(3.141592654F);
        System.out.println(3.141592654);
        //浮点数的使用陷阱
        double number1=2.7;
        double number2=8.1/3;
        System.out.println(number1);
        System.out.println(number2);//打印的是一个接近2.7的数   计算机不知道8.1后面还有没有数字
        //所以对小数进行判断时,用两个数差值的绝对值,在某个精度范围判断
        if(Math.abs(number1-number2)<0.000001){
            System.out.println("差度非常小,到我的规定精度,认为相等");
        }
        //在java中,char本质是一个整数,在默认输出时,是unicode码对应的字符
        char number3=97;
        System.out.println(number3);
        System.out.println(number3+1);//char类型可以进行运算
        char number4='a';
        //要输出对应的数字,可以(int)字符
        System.out.println((int)number4);
        //java允许使用转义字符
        char number5='\n';
        *//*
        字符串存储 'a'--->码值97--->二进制---->存储
              读取 二进制--->码值--->'a'--->显示

         ASCII一个字节表示,可以表示256个字符,但只用了128个  缺点:不能表示所有字符
         Unicode字母和数字同一都是两个字节  Unicode是兼容ASCII码 缺点浪费空间
         utf-8 大小可变的编码(根据不同的符号来变化字节长度),互联网使用最广的一种,对Unicode的改进  字母使用一个字节 汉字用三个字节
         gbk字母一个字节,汉字两个字节 gbk>gb2312
         big5码 (繁体中文,香港台湾)
         *//*
        //boolean类型,不能用0或非0值替代false和true,这点和C语言不同

        //基本类型数据转化 精度小到大(自动类型转换) 大到小(强转)
        byte number6=10;//把具体值赋给number6时,先判断是否在byte范围内
        int number7=number6;//如果是变量赋值,则先判断类型
        //byte(short)和char之间不会相互转换,他们三者计算时,先转换为int类型 boolean不参与转换
        byte number8=1;
//        byte number9=number6+number8;//会报错 左边int右边byte
        int number9=number6+number8;//正确
        System.out.println(number9);
        //强转只针对于最近的操作数有效 (int)5*8  把5强转为int再相乘
        //基本数据类型转String
        String number10=number6+"";//基本类型值+""
        System.out.println(number10);
        //String转基本数据类型(首先格式要正确,确保数据的有效性,"hello"就不能转化成基本数据)
        String number11="123";
        byte number16=Byte.parseByte(number11);
        short number17=Short.parseShort(number11);
        int number12=Integer.parseInt(number11);
        double number13=Double.parseDouble(number11);
        float number14=Float.parseFloat(number11);
        long number15=Long.parseLong(number11);
        boolean number18=Boolean.parseBoolean("true");
        System.out.println(number12);
        System.out.println(number13);
        System.out.println(number14);
        System.out.println(number15);
        System.out.println(number16);
        System.out.println(number17);
        System.out.println(number18);
        double number19=10/4;//右边是int相除
        double number20=10.0/4;
        System.out.println(number19);//打印结果2.0
        System.out.println(number20);//打印结果2.5
        //取模的本质 a%b=a-(a是小数则加int)a/b*b
        System.out.println(10%-3);//套公式  10-10/(-3)*(-3) 1
        System.out.println(-10%3);//   -10-(-10)/3*3   -1
        System.out.println(-10%-3);//   -10-(-10)/(-3)*(-3)   -1

        // 先认识一下:instanceof(检查是否是类的对象)
        //逻辑运算符 && ||(短路效果,效率高)   & |(逻辑与,逻辑或)  ^逻辑异或(当a和b不同时,则结果为true)
        boolean number21=(10>5)^(5<10);
        boolean number22=(10<5)^(5<10);
        System.out.println(number21);
        System.out.println(number22);
        //复合赋值运算符会进行类型转换
        byte number23=5;
        number23 +=2;//numebr23=(byte)(number23+2)
        System.out.println(number23);
        number23++;//number23=(byte)(number23+2)
        System.out.println(number23);

        //运算符具有优先级 只有单目运算符,赋值运算符是从右向左运算的

        *//*标识符的规则(必须执行)
        标识符由26个英文字母,0-9和 _ 或 $ 组成 ; 不可以数字开头;不可以使用关键字和保留字
        保留字:现在版本尚未使用,但以后可能会作为关键字使用
        规范:包(小写) com.lsp.day  包包括:接口,类和异常
              类名/接口  大驼峰
              变量名/方法名  小驼峰
              常量名 全部大写

        //进制  二进制 0b/oB 开头
                八进制 0开头
                十六进制 0x/0X开头
        // 0的反码补码都是0 计算机以补码方式来运算,看运算结果要看原码
         *//*
        System.out.println(~-2);//打印1
        // -2原码 10000000 00000000 00000000 00000010  反码 11111111 11111111 11111111 11111101 补码11111111 11111111 11111111 11111110
        //按位取反(符号位也变) 00000000 00000000 00000000 00000001

        //算数右移(/2) >>  算数左移(*2)<<  无符号右移(逻辑右移)>>>

    }
}*/
/*public class One{
    public static void main(String[] args){
        //导包  import java.util.Scanner
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入姓名");
        String name=scanner.next();
        System.out.println("请输入性别");
        char gender= scanner.next().charAt(0);
        System.out.println("请输入年龄");
        int age=scanner.nextInt();
        System.out.println("请输入价格");

        double price=scanner.nextDouble();
        System.out.println("姓名:"+name+"性别"+gender+"年龄:"+age+"价格:"+price);
        double number1=23d;//不会报错 跟25f类似
        //switch(表达式对应一个值,可以是byte,short,int,char,enum,String)
        //case常量 表达式的数据类型应和case后的一致,或者可以自动转换char(int)
    }
}*/

//API  Java字典

/*public class One{
    public static void main(String[] args){

        //for只有一条语句,可以省略{},建议不要省略
        //初始化和调整部分可以写在其他地方
        *//*int frequency=1;
        for(;frequency<5;){
            System.out.println("HelloWorld");
            frequency++;
        }
        System.out.println("====================");
        //初始化可以有多条语句,但要类型一致;调整部分也可以多条语句
        for(int frequency1=2,frequency2=10;frequency1<frequency2;frequency1++,frequency2--){
            System.out.println("你好,世界");
        }*//*

        //for while do...while嵌套循环时,最多不要超过三层,否则代码可读性很差  外层循环n次,内层循环m次,总共循环m*n

        //打印矩形
       *//* int total=5;//先死后活
        for (int i = 0; i < total; i++) {//层数
            for (int i1 = 1; i1 < 3; i1++) {
                System.out.print("*****");
            }
            System.out.println();
        }
        //打印金字塔
        for (int i = 1; i <= total; i++) {//层数
            for(int k=1;k<=total-i;k++){
                System.out.print(" ");
            }
            for(int m=1;m<=2*i-1;m++){
                System.out.print("*");
            }
            System.out.println();
        }
        //打印空心金字塔
        for (int i = 1; i <= total; i++) {//层数
            for(int k=1;k<=total-i;k++){
                System.out.print(" ");
            }
            for(int m=1;m<=2*i-1;m++){
                if(m==1||m==2*i-1||i==total){
                    System.out.print("*");
                }else{
                    System.out.print(" ");
                }
            }
            System.out.println();
        }*//*
 *//* label1:
        for (int i = 0; i < 5; i++) {
            System.out.println(Math.random());//返回一个double值,大于0.0小于1.0
        }
        label2:
        for (int i = 0; i < 5; i++) {
            System.out.println("HelloWorld");
            if(i==2){
                break label2;//break 和continue都可以通过标签指明要终止那一块语句块
            }
        }
        //字符串比较 equals
        String name="从善";
        System.out.println("阿伟".equals(name));//推荐,可以避免空指针
        System.out.println(name.equals("从善"));
*//*
        //简单实现登陆界面
        *//*Scanner three=new Scanner(System.in);
        String name="";
        String password="";
       while(true) {
            System.out.println("请输入用户名");
            name=three.next();
            System.out.println("请输入密码");
            password=three.next();
            if("阿伟".equals(name)&&"666".equals(password)){
                System.out.println("恭喜你,登陆成功");
                break;
            }
        }*//*

       //return写在方法,跳出方法;写在main方法,结束程序
        //判断一个数是否是水仙花数
       *//* Scanner one=new Scanner(System.in);
        System.out.println("请输入数字");
        int number=one.nextInt();
       int number1=number/100;
       int number2=number%100/10;
       int number3=number%10;
       if(number1*number1*number1+number2*number2*number2+number3*number3*number3==number){
            System.out.println(number+"是水仙花数字");
        }else{
            System.out.println("不是");
        }*//*

 *//*for(char word='a';word<='z';word++){
            System.out.print(word);
        }
        System.out.println();
        for(char word='A';word<='Z';word++){
            System.out.print(word);
        }*//*

        //求1+(1+2)+(1+2+3)+(1+2+3+4)+(1+2+...+100)
        *//*int sum=0;
        for(int i=1;i<=100;i++){
            for(int n=1;n<=i;n++){
                sum+=n;
            }
        }
        System.out.println("sum="+sum);*//*

        //数组的反转
       *//* int[] array={11,22,33,44,55,66};
        //int array[]={11,22,33,44,55,66};//也可以这样写
        int temp=0;
        for(int i=0;i<array.length/2;i++){//数组反转3次就可以亮了
            temp=array[array.length-1-i];
            array[array.length-1-i]=array[i];
            array[i]=temp;
        }
        for(int i=0;i<array.length;i++){
            System.out.print(array[i]+"   ");
        }
        System.out.println();*//*
        //数组扩容
        Scanner one=new Scanner(System.in);
        int[] array={1, 2,3};
        do{
            int[] arrayNew=new int[array.length+1];
            for (int i = 0; i < array.length; i++) {
                arrayNew[i]=array[i];
            }
            System.out.println("请输入你要添加的元素");
            arrayNew[arrayNew.length-1]=one.nextInt();
            array=arrayNew;//将array扩容
            for (int i = 0; i < array.length; i++) {
                System.out.print(array[i]+"\t");
            }
            System.out.println("是否需要继续添加Y/N");
            char key=one.next().charAt(0);
            if(key=='N'){
                break;
            }
        }while(true);

    }

}*/

//排序:内部排序;外部排序(大数据数据量过大)
/*public class One {
    public static void main(String[] args) {
        //冒泡排序:每一轮排序只能确定一个数
        *//*int[] array={24,63,48,56,99};
        for(int i=0;i<array.length-1;i++) {
            for (int j = 0; j < array.length-1-i; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+"\t");
        }*//*

        //查找古力娜扎
        *//*String[] name={"古力娜扎","马尔扎哈","迪丽热妈","迪丽热巴"};
        System.out.println("请输入要查找的名字");
        Scanner input=new Scanner(System.in);
        int index=-1;
        for(int i=0;i<name.length;i++){
            if((input.next()).equals(name[i])){
                System.out.println("恭喜你找到了"+"下标是"+i);
                index=i;
                break;
            }
        }
        if(-1==index){
            System.out.println("抱歉,没有找到");
        }*//*

        //二维数组每个元素是一维数组
       *//* int[][] array1={{0,1,2},{3,4,5},{6,7,8}};
        int[][] array2=new int[3][];
        int[] array3[];//也可以这样写
        //动态数组---列数不确定用   //打印1 22 333 4444 ……
        for(int i=0;i<array2.length;i++){//遍历array2每一个数组
            array2[i]=new int[i+1];//给每个数组开辟空间
            for(int j=0;j<array2[i].length;j++){
                array2[i][j]=i+1;

            }
        }*//*

        //打印杨辉三角 第n行n个元素
       *//* int[][] array3 = new int[10][];
        for (int i = 0; i < array3.length; i++) {
            array3[i] = new int[i + 1];
            for (int j = 0; j < array3[i].length; j++) {
                if (j == 0 || j == array3[i].length - 1) {
                    array3[i][j] = 1;
                } else {
                    array3[i][j] = array3[i - 1][j] + array3[i - 1][j - 1];
                }
            }
        }
        for (int i = 0; i < array3.length; i++) {
            for (int j = 0; j < array3[i].length; j++) {
                System.out.print(array3[i][j] + "\t");
            }
            System.out.println();
        }
*//*
        //已有升序数组,插入一个元素,仍是升序数组
        int[] array4={10,20,30,40,50};
        int insertNum=23;
        int index=-1;
        for(int i=0;i<array4.length;i++){
            if(insertNum<=array4[i]){
                index=i;
                break;
            }
        }
        if(-1==index){
            index=array4.length;
        }
        int[] array4New=new int[array4.length+1];
        for(int i=0,j=0;i<array4New.length;i++){
            if(i!=index){
                array4New[i]=array4[j];
                j++;
            }else{
                array4New[i]=insertNum;
            }
        }
        array4=array4New;
        for(int i=0;i<array4.length;i++){
            System.out.print(array4[i]+"\t");
        }

    }
}*/

444

/*public class Demo1 {
    public static void main(String[] args) {
        Person person1 = new Person("奥特曼", 18);
        Person person2 = new Person("奥特曼",18);
        System.out.println(person1.equals(person2));//如果不重写,则输出结果为false
        String one=new String("abc");
        String two=new String("abc");
        System.out.println(one.equals(two));//String有方法的重写

 *//*
    hashCode 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的;哈希值是根据地址号来的,不能完全将哈希值等价于地址(java用的是虚拟机)
    toString方法 默认返回:全类名(包名+类名) + @ + 哈希值的16进制  子类往往重写toString方法
 *//*
        System.out.println(person1.toString()+"\t"+person1.hashCode());
        System.out.println(person1+"\t"+person1.hashCode());//  person1等价于person1.toString()

        //当某个对象没有任何引用时,则jvm就认为这是一个垃圾,就会使用垃圾回收机制销毁对象,在销毁对象前,会先调用finalize方法
        //垃圾回收调用是由系统来决定,也可以通过System.gc()主动触发垃圾回收装置

        Person person3=new Person("汤姆");
        person3=null;
        //这是person3相当于一个垃圾  (子类也可以重写finalize方法,做一些释放资源的操作(数据链接+打开文件等等))
        //如果不重写,则就会调用Object类的finalize,即默认处理
        System.gc();//主动调用垃圾回收器
        System.out.println("程序结束");


    }
}

class Person{
    private String name;
    private int age;

    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;
    }

public boolean equals(Object obj){
        if(this==obj){
            return true;
        }
        if(obj instanceof Person){
            Person one=(Person)obj;
            return this.name.equals(one.name)&&this.age==one.age;
        }
        return false;
    }

}*/


/*再断点调试过程中,是运行状态,是一对象的运行类型来执行
F7(跳入方法内) F8(逐行执行代码) Shift + F8(跳出方法) F9(执行到下一个断点)
 */

/*import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

//模拟微信零钱通
public class Demo1 {
    public static void main(String[] args) {
        boolean label=true;
        Scanner scanner=new Scanner(System.in);
        String choose="";

        //把收益和消费可以保存到数组,也可以使用对象,简单的话可以String拼接
        String begin="--------零钱通明细--------";

        //1.完成收益转账
        double money=0;
        double consume=0;
        Date date = null;//date 是 Java.util.Date类型 表示日期
        //date = new Date();System.out.println(date); 这样打印格式很怪,不符常理
        SimpleDateFormat myDate=new SimpleDateFormat("yyyy-MM-dd HH:mm");//("yyyy-MM-dd HH:mm")将日期格式化

        //2.消费 定义新的变量,保存消费原因
        String name="";

        do{
            System.out.println("=========零钱通菜单=========");
            System.out.println("\t\t\t1 零钱通明细");
            System.out.println("\t\t\t2 收益转账");
            System.out.println("\t\t\t3 消费");
            System.out.println("\t\t\t4 退     出");

            System.out.println("请选择1-4");
            choose=scanner.next();
            switch(choose){
                case "1":
                    System.out.println(begin);
                    break;
                case "2":
                    System.out.print("2 收益转账金额");
                    money=scanner.nextDouble();
                    //检验 这个if过不去直接不执行下面代码
                    if(money<=0){
                        System.out.println("收益转账应大于等于0");
                        break;
                    }
                    consume+=money;//记录总金额
                    date =new Date();//获取当前日期
                    begin+="\n收益转账\t+"+money+"\t"+myDate.format(date)+"\t"+consume;//拼接信息
                    System.out.println("收益转账成功");
                    break;
                case "3":
                    System.out.println("3 消费金额");
                    money=scanner.nextDouble();
                    if(money<=0||money>consume){
                        System.out.println("您消费的金额应在0-"+consume);
                        break;
                    }
                    System.out.println("消费说明:");
                    name=scanner.next();
                    consume-=money;
                    date =new Date();
                    begin+="\n"+name+"\t-"+money+"\t"+myDate.format(date)+"\t"+consume;
                    System.out.println("消费成功");
                    break;
                case "4":
                    String choice="";
                    //代码风格:一段代码实现一个功能 更加清晰明白
                    while(true){//用户输入Y/N否则一直循环
                        System.out.println("你确认要退出嘛?  Y/N");
                        choice=scanner.next();
                        if("Y".equals(choice)||"N".equals(choice)){
                            break;
                        }
                    }
                    if(choice.equals("Y")){//对用户输入进行判断是否退出
                        label=false;

                    }
                    break;
                default:
                    System.out.println("输入错误,请重新选择");
            }
        }while(label);
        System.out.println("退出零钱通项目");
    }
}*/

//对象运行类型是可以变化的,可以通过getClass()来查看运行类型
/*public class Demo1 {
    public static void main(String[] args) {
        AAA.say();//因为一个方法是static(这就是静态方法)可以直接使用
        *//*AAA one=new BBB();
        AAA two=one;
        System.out.println("one的运行类型是"+one.getClass());
        one=new CCC();
        System.out.println("one的运行类型是"+one.getClass());
        one=two;
        System.out.println("one的运行类型是"+one.getClass());*//*
    }
}
class AAA{
    static void say(){
        System.out.println("静态方法可以直接通过类名称调用");
    }

}
class BBB extends AAA{

}
class CCC extends BBB{

}*/

//在实际开发中,公司会提供相应的工具类和开发类,可以提高效率
/*

class Child{
    private String name;//  普通属性/普通成员变量/非静态属性/非静态成员变量;实例对象是每个对象独享的
    //public static int count;//类变量必须遵守相关访问权限
    static public int count;//也可以这样写,但不推荐
    */
/*  count为类变量(静态变量) 该变量最大特点是会被Child实例化对象共享
    在java7,java8等版本这个count放在方法区的静态域里面
    但现在static 变量保存在Class实例的尾部 Class对象确实在堆中,static对象在类的加载的时候就生成了

     *//*


    public Child(String name) {
        this.name = name;
    }
    public void join(){
        System.out.println(name+"加入了战斗");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        //通过类名.类变量名访问(推荐)
        Child.count++;//类变量是随着类的加载而创建,所以即使没有实例化对象也可以访问
        Child child1=new Child("狐狸精");

        child1.join();
        child1.count++;//通过对象名.类变量名
        Child child2=new Child("白骨精");
        child2.join();
        Child.count++;
        System.out.println("共有"+child1.count+"个角色");
        System.out.println("共有"+child2.count+"个角色");
    }
}
*/

/*class Student{
    private String name;
    private static double cost;

    public Student(String name) {
        this.name = name;
    }

    //静态方法不允许使用和对象有关的关键字(this和super)
    //类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区
    //类方法(静态方法)只能访问静态变量和静态方法
    public static void sum(double cost){//当方法使用static修饰后,该方法就是静态方法
        Student.cost+=cost;
    }
    *//*static public void sun(double cost){//  也可以这样写,但不推荐
        Student.cost+=cost;
    }*//*
    public static void show(){
        System.out.println("总费用有:"+Student.cost);
    }
}

public class Demo1 {
    public static void main(String[] args) {
    *//*
    1.java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public
    2.java虚拟机在执行类的main()方法不必创建对象,所以方法必须是static
    3.该方法接受String类型的数组参数,该数组中保存执行java命令时传递给所运行类的参数
     *//*
        for (int i = 0; i < args.length; i++) {

            //动态传值 Program arguments
            System.out.println("第"+(i+1)+"参数"+args[i]);
        }

        //Student.sum(200);//对象名.类方法名  也可以对类方法的调用
        //Student.sum(25.2);
        //Student.show();
        //如果我们不希望创建实例,就可以调用某个方法(当成工具来用);这时,把方法做成静态方法就非常使用
        //要想访问对象中的非静态成员,必须创建一个实例化对象

    }
}*/



/*
class AA{

    */
/*代码化块(初始化块)(不同通过调用或类显式调用,而是加载类或创建对象时隐式调用)
相当于另一种形式的构造器(对构造器的补充机制),如果多个构造器中都有重复的语句,可以提到初始化块中,提高代码的重复性
 当我们不管调用那个构造器,创建对象,都会先调用代码块的内容
 *//*


    {//普通代码块
        //普通代码块被创建一次就会调用一次
    };//  ; 可以写,也可以不写

    static{//静态代码块
        //静态代码块随着类的加载而执行,并且只会执行一次(1. new对象时  2. 创建对象实例,父类也会被加载,父类先加载子类后加载  3. 使用类的静态成员和静态方法,但普通代码块不会执行)
    }

    private static int number=getNUM();//静态属性初始化

    public static int getNUM(){
        return 100;
    }
    */
/*
    调用顺序:1.父类静态代码块或静态属性初始化(都有按他们定义顺序调用)
             2.子类静态代码块或静态属性初始化(都有按他们定义顺序调用)
              3.父类调用普通代码块或普通属性初始化(都有按他们定义顺序调用)
              4.父类的构造方法
              5.子类调用普通代码块或普通属性初始化(都有按他们定义顺序调用)
              6.子类的构造方法
       静态代码块只能直接调用调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员
     *//*


}
*/

/*
  设计模式(在大量的实践中优选的代码结构,编程风格,以及思考问题的方式)
  单例设计模式(对某个类只能存在一个对象(通常时重量级对象)实例,并且该类只提供一个取得其对象实例的方法)(两种方式1.饿汉式2.懒汉式)

    两者区别:1.饿汉式在类的加载就创建了对象实例,而懒汉式在使用时才创建
              2.饿汉式(如果一个对象是咧都没有使用,就会浪费资源),懒汉式(存在线程问题)
 */


/*class Girl{//饿汉式
private String name;

private Girl(String name) {//1.将构造器私有化
        this.name = name;
        }

private static Girl girl=new Girl("小红红");//2.在类中直接创建

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

public static Girl get(){//3.提供一个公共的static方法,返回girl对象
        return girl;

        }
        }
public class Demo1 {
    public static void main(String[] args) {
        Girl one=Girl.get();
        System.out.println(one);
        Girl two=Girl.get();
        System.out.println(two);
        System.out.println(one==two);
    }
}*/
/*class Girl{
    private String name;
    private static Girl girl;//定义一个static静态属性对象

    private Girl(String name) {//1.将构造器私有化
        this.name = name;
    }


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

    public static Girl get(){
        if(girl==null){//如果没有创建对象
            girl=new Girl("小可爱");
            //只有当用户使用get时,才返回girl对象,下次再使用,会返回上次创建的girl对象
        }
        return girl;

    }
}
public class Demo1 {
    public static void main(String[] args) {
        Girl one=Girl.get();
        System.out.println(one);
        Girl two=Girl.get();
        System.out.println(two);
        System.out.println(one==two);
    }
}*/

/*
   final中文意思:最后的,最终的 可以修饰类,属性,方法和局部变量
   final类不能继承,但可以实例化对象
   如果类不是final类,但是含有final方法,则该方法不能重写,但是可以继承
   一般来说,如果一个类是final类,就没有必要再将方法修饰成final方法
   final不能修饰构造方法(即构造器)
   final和static搭配使用,效率更高,不会导致类加载
   包装类(Integer,Double,Float,Boolean等都是final) String 也是final
 */
/*final class Person{//  Person不能被其他类继承

    //final修饰的属性又叫常量,常量名一般大写;必须赋初值
    //public final double NUM_ONE=0.00;//不希望某个属性的值被修改

    public final double NUM_ONE;
    //public static final double NUM_TWO=0.02;//如果final修饰的属性是静态的;直接赋值
    public static final double NUM_TWO;
    static{
        NUM_TWO=0.02;//在静态代码块中赋值
        System.out.println("嘎嘎嘎,静态代码块执行");
    }


    *//*public Person() {
        NUM_ONE=0.01;//在构造器中赋值
    }*//*
    {
        NUM_ONE=0.01;//在代码块中赋值
    }

    public final void hello(){// hello不能被子类重写

        final double NUM=0.01; //不希望局部变量被修改

    }

}*/

//当父类的某些方法需要声明,但又不确定如何实现,可以将其为抽象方法,这个类就是抽象类
// abstract只能修饰类和方法,不能修饰其他的(抽象类本质是类)
//抽象方法不能使用private,final和static来修饰,因为这些关键字和重写违背
/*abstract class Animal{//抽象类不一定含有abstract方法;一但包含了abstract方法,则类必须声明为abstract

    public abstract void eat();//(抽象方法没有实现的方法,没有实现是指没有方法体)

}
abstract class Cat extends Animal{
    //如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非他自己也声明为abstract类
}
class Dog extends Animal{
    public void eat(){

    }
}*/



/*public class Demo1 {

    public static void main(String[] args) {

        long start = System.currentTimeMillis();//得到开始时间
        long num = 0;
        for (long i = 1; i < 80000; i++) {
            num += i;
        }
        long end = System.currentTimeMillis();//得到结束时间
        System.out.println("执行时间" + (end - start));
    }

}*/

//接口的修饰符只能是public 和默认(这点和类很像)
/*public interface Demo1 {//接口不能被实例化

     int number=10;//等价于 public static final int number = 10;

    public void job();//在接口中,抽象方法可以省率abstract关键字

    //在Jdk7前,接口所有方法都没有方法体,即都是抽象方法
    public static void input(){//在Jdk8后,可以有静态方法
        System.out.println("开始输入");
    }

    void out();

    default public void stop(){//在Jdk8后,可以有默认实现方法,需要default关键字修饰
        System.out.println("停止工作");
    }
}
class Worker implements Demo1{//  implements实现接口(需要将该接口所有抽象方法都实现)

    @Override
    public void job() {
        System.out.println("Usb接口开始工作");
    }

    @Override//Alt + Enter
    public void out() {//接口所有方法是public方法

    }
}

interface Usb1{

}
interface Usb2{

}
class Usb implements Usb1,Usb2{//一个类可以实现多个接口

}

interface MyUsb extends Usb1,Usb2{//接口不能继承其他类,但可以继承多个接口

}*/

/*interface Test{
    int number=100;
}
class MyTest implements Test{

}
public class Demo1 {
    public static void main(String[] args) {
        MyTest test=new MyTest();
        System.out.println(test.number);
        System.out.println(Test.number);//接口名.属性名
        System.out.println(MyTest.number);// number是static修饰过的
    }
}*/

/*
class Monkey{
    private String name;

    public Monkey(String name) {
        this.name = name;
    }
    public void ability(){
        System.out.println("猴子捞月");
    }
}

interface Fish{
    void swimming();
}

class WuKong extends Monkey implements Fish{
    //当子类继承父类,就拥有了父类的功能;当子类需要扩展功能,可以通过实现接口的方法扩展(可以理解为接口是对java单继承的补充)
    public WuKong(String name) {
        super(name);
    }

    @Override
    public void swimming() {
        System.out.println("化鱼下五洋捉鳖");
    }
}
public class Demo1 {
    public static void main(String[] args) {
        WuKong one=new WuKong("六耳猕猴");
        one.swimming();
        one.ability();
    }
}
*/

/*
接口(设计好各种规范,让其他类实现)和继承(解决代码复用性和维护性)
接口(like-a)比继承(is-a)更加灵活
 */
/*interface Usb{
    void job();
}

class One implements Usb{
    @Override
    public void job() {
        System.out.println("One开始工作了");
    }
    public void stop(){
        System.out.println("太累了,发烫");
    }
}
class Two implements Usb{
    @Override
    public void job() {
        System.out.println("Two开始工作了");
    }
}

public class Demo1{
    public static void main(String[] args) {
        //接口多态的体现
        //接口类型的变量 one可以指向实现Usb接口的对象实例
        *//*Usb one=new One();//和继承 AAA one= new BBB(); one=new CCC();  AAA是BBB和CCC的父类
        one=new Two();*//*

        //多态数组
        Usb[] usbs=new Usb[2];
        usbs[0]=new One();
        usbs[1]=new Two();
        for(int i=0;i<usbs.length;i++){//遍历usbs数组
            usbs[i].job();//动态绑定
            if(usbs[i] instanceof One){//进行向下转型 调用One的特有方法
                ((One)usbs[i]).stop();
            }
        }
    }
}*/

/*
 一个类又嵌套了另一个类,被嵌套的类成为内部类 嵌套其他类的类称为外部类 内部类最大的特点就是可以直接访问私有属性

 */
/*
class One{//类的五大成员:1.属性 2.方法 3.构造器 4.代码块 5.内部类
    private int number=100;//属性

    public One(int number) {//构造器
        this.number = number;
    }
    public void hi0(){//方法

    }
    public void hi(){
        System.out.println("方法执行了");
        //不能添加访问修饰符,但可以用final修饰
        final class One2{//局部内部类(本质是一个类)(地位是一个局部变量,外部其他类不能访问)
            //如果外部类和局部类的成员重名,默认遵循就近原则,访问外部类的成员,则可以使用(外部类名.this.成员)
            private int number=200;
            public void hi1(){
                //可以直接访问外部类的所有成员,包含私有的
                //One.this本质就是外部类对象,即那个对象调用了number,One.this就是那个对象
                System.out.println("内部类的number="+number+"外部类的number="+One.this.number);
            }
        }
        //创建One2对象,就可以调用即可
        One2 one2=new One2();
        one2.hi1();
    }



    {//代码块
        System.out.println("代码块执行了");
    }
    class One1{//内部类

    }
}
public class Demo1 {
    public static void main(String[] args) {
        One a=new One(100);
        a.hi();
    }
}
*/

/*interface Usb{
    public void voice();
}

abstract class Usb1{
    abstract void test();
}
public class Demo1 {
    public static void main(String[] args) {
        *//*
        如果一个类只使用一次,后面不再使用,就可以用匿名对象来简化开发
        匿名对象类(1.本质是类 2.内部类 3.该类没有名字 4.同时还是一个对象)
        phone的编译类型 Usb
        phone的运行类型 匿名对象类(匿名对象类只能使用一次) XXX => Demo1$1
        (jdk底层在创建匿名对象Demo1$1,立马创建了Demo1$1实例,并把地址返回给phone)

        底层:  class XXX implements Usb{
                  @Override
                   public void voice() {
                    System.out.println("手机播放音乐");
                  }
                }
         *//*
       *//* Usb phone=new Usb(){

            @Override
            public void voice() {
                System.out.println("手机播放音乐");
            }
        };
        phone.voice();
        System.out.println("phone的运行类型="+phone.getClass());

        //基于抽象类的匿名对象类
        *//**//*Usb1 usb1=new Usb1() {
            @Override
            void test() {
                System.out.println("test执行了");
            }
        };
        usb1.test();*//**//*

        //也可以直接调用
        new Usb1() {
            @Override
            void test() {
                System.out.println("test执行了");
            }
        }.test();*//*

        test1(new Usb(){//匿名对象当作实参之间传递(最佳实践)

            @Override
            public void voice() {
                System.out.println("我要说话了");
            }
        });

    }
    public static void test1(Usb usb1){
        usb1.voice();
    }
}*/

/*
class Usb{
    private int number=100;

    */
/*//*
/可以添加任意访问修饰符(public,protected,默认,private),因为它的地位是一个成员
    class Usb1{//成员内部类
        public void say(){
            //可以直接访问外部类的所有成员,包含私有的
            System.out.println("number="+number);
        }
    }
    //外部类访问---创建对象再访问
    public void test(){
    Usb1 usb1=new Usb1();
    usb1.say();
    }
    //方法,返回一个Usb实例
    public Usb1 getUsb1(){
        return new Usb1();
    }*//*

    static class Usb3{//静态内部类(static修饰)只能访问外部类的所有静态成员,但不能访问非静态成员
        public void say(){
            System.out.println("hi");
        }
    }
    public void test1(){
        Usb3 usb3=new Usb3();
        usb3.say();
    }
    //方法,返回一个Usb3实例
    public Usb3 getUsb3(){
        return new Usb3();
    }
    public static Usb3 getUsb4(){
        return new Usb3();
    }
}
public class Demo1 {
    public static void main(String[] args) {
        */
/*Usb usb=new Usb();
        usb.test();

        //外部其他类,使用成员内部类的两种方式
        //第一种方法  usb.new Usb1();   相当于new Usb1()当作是usb成员
        Usb.Usb1 usb1=usb.new Usb1();
        usb1.say();
        //第二种方法 在外部类中,编写一个方法可以返回Usb1对象
        Usb.Usb1 usb2=usb.getUsb1();
        usb2.say();*//*


        Usb usb=new Usb();
        usb.test1();
        //外部其他类,使用成员内部类的两种方式
        //第一种方式:静态内部类可以通过类名直接访问
        Usb.Usb3 usb3=new Usb.Usb3();
        usb3.say();
        //编写一个方法,可以返回静态内部类实例对象
        Usb.Usb3 usb4=usb.getUsb3();
        usb4.say();

        Usb.Usb3 usb5=Usb.getUsb4();
        usb5.say();

        //内部类  定义在局部位置(方法块/代码块) 1.局部内部类  2.匿名内部类
                  定义在成员位置 1.成员内部类 2.静态内部类
    }
}
*/

//季节是有限的几个值,只读不修改,这时我们需要一个新的设计理念---枚举类
//class Season{//类
// 使用enum关键字,就不能继承其他类了,以为enum会隐式继承Enum  但枚举类和其它类一样,可以实现接口
/*
enum Season{ // enum 替代 class

    */
/*//*
/3.在Season内部,直接创建固定对象  优化,加入final修饰符(将构造器私有化) 枚举对象名大写(常量命名规范)
    public static final Season SPRING = new Season("春天");
    public static final Season SUMMER = new Season("夏天");
    public static final Season AUTUMN = new Season("秋天");
    public static final Season WINTER = new Season("冬天");*//*


    //多个常量 ,间隔   一定要写在最前面  WHAT() 也可以写成 WHAT
    SPRING("春天"),SUMMER("夏天"),AUTUMN("秋天"),WINTER("冬天"),WHAT(),WHY;

    private String name;


    private Season(String name){//1.将构造器私有化 防止new
        this.name=name;
    }

    Season() {//无参构造器
    }

    private String getName() { //2.去掉setXXX方法 防止属性被修改 (枚举对象值通常为只读)
        return name;
    }

    */
/*
        Enum的toString()
        public String toString(){
                return name;
        }
     *//*

   */
/* @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                '}';
    }*//*

}
public class Demo1 {
    public static void main(String[] args) {
        System.out.println("1:"+Season.SPRING);
        Season autumn=Season.AUTUMN;

        //输出枚举对象的名字
        System.out.println("2:"+autumn.name());

        // ordinal() 输出该对象的次序
        System.out.println("3:"+autumn.ordinal());

        */
/*//*
/ 从反编译看 values() 返回 Season[]
        Season[] array=Season.values();
        for(int i=0;i< array.length;i++){//普通for循环
            System.out.println(array[i]);
        }
        System.out.println("=========");
        for(Season season:array){//增强for循环
            System.out.println(season);
        }
        int[] numbers={1,2,9};
        for(int i:numbers){//增强for循环
            System.out.println("i="+i);
        }*//*


        // valueOf 寻找字符串,字符串必须是已有的常量名,否则报异常
        Season autumn1=Season.valueOf("AUTUMN");
        System.out.println("autumn1="+autumn1);
        System.out.println(autumn1==autumn);

        // compareTo 比较两个枚举常量的编号
        System.out.println(Season.AUTUMN.compareTo(Season.SPRING));

    }
}
*/
/*
    @Override 该注解只能用于方法  @interface 不是interface,是注解类  是jdk1.5之后加入的
    @Target 是修饰注解的注解 称为元注解
    如果写了@Override逐渐,编译器会去检查是否真的重写了父类的方法;的确重写了,则编译器通过,否则编译器报错

    @Deprecated 修饰某个元素,表示该元素已过时 不推荐使用,但仍可以使用  @Deprecated作用可以做到新旧版本的兼容和过渡
    修饰方法,类,字段,包,参数

    @SuppressWarnings({""})   {""}可以显示你希望不显示的警告信息  抑制编译器警告   @SuppressWarnings({"unused","unchecked"})

    @Retention 是指该注解可以保留多长时间
    @Retention(RetentionPolicy.SOURCE) (编译器将注解记录在java源文件)
    @Retention(RetentionPolicy.CLASS)   (编译器将注解记录在class文件)
    @Retention(RetentionPolicy.RUNTIME)   (编译器将注解记录在class文件,当运行java程序,JVM会保留注解)

    @Inherited  如果某个类被@Inherited修饰,则其子类自动具有该注解
 */

/*
interface Sub{
    public double sub_(double number1,double number2);
}
class Counter{
    public void start(Sub sub,double number1,double number2){
        double result=sub.sub_(number1,number2);
        System.out.println("计算的结果是result="+result);
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Counter counter=new Counter();
        counter.start(new Sub(){

            @Override
            public double sub_(double number1, double number2) {
                return number1+number2;
            }
        },10.10,100);
    }
}
*/

/*interface Vehicles{
    public void work();
}

class Horse implements Vehicles{

    @Override
    public void work() {
        System.out.println("一般情况下,使用白龙马前进");
    }
}
class Boat implements Vehicles{

    @Override
    public void work() {
        System.out.println("拿东海老王八当船过河");
    }
}
class VehiclesFactory{//创建交通工具工厂类

    private static Horse horse=new Horse();
    public static Horse getHorse(){//将方法做成static,不创建交通工具工厂类,也可以调用对象
        return horse;//白龙马创建一次就可以了
    }
    public static Boat getBoat(){
        return new Boat();
    }
}
class Person{
    private String name;
    private Vehicles vehicles;

    public Person(String name, Vehicles vehicles) {
        this.name = name;
        this.vehicles = vehicles;
    };
    public void passRiver(){
        if(!(vehicles instanceof Boat)){
            vehicles=VehiclesFactory.getBoat();
        }
       vehicles.work();
    }
    public void usually(){
        if(!(vehicles instanceof Boat)){
            vehicles=VehiclesFactory.getHorse();
        }
        vehicles.work();
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Person tang=new Person("唐僧",new Horse());
        tang.passRiver();
        tang.usually();
    }
}*/












 555



/**
 * @author 耿世伟
 * @version 1.0
 */
/*
    程序执行中发生不正常情况称为异常(开发过程中语法错误和逻辑错误不是异常)
    异常分为两类    1.Error(错误) Jvm虚拟机无法解决的严重错误 比如栈溢出,内存不足
                    2.Exception(分为运行异常和编译异常(发生在java源文件))  一般性错误
    编译异常是必须处置的异常;运行时异常可以不做处理,因为这类异常很常见,若全处理可能会对程序可读性和运行效率产生影响
 */
/*public class Demo2 {//运行异常
    public static void main(String[] args) {
       *//* int number1=100;
        int number2=0;
        //出现异常程序崩溃;这样的程序也不算致命的错误,导致整个程序崩溃
        //java设计者,提供了一个叫 异常处理机制来解决问题  try-catch处理机制来解决(快捷键 ctrl+alt+t)
        try {//代码可能有异常
            int result=number1 / number2;
        } *//**//*catch (NullPointerException e){
            System.out.println("空指针异常="+e.getMessage());
        }
        catch (Exception e) {//当异常发生时,后面的代码不在执行,系统将异常封装为Exception对象e,传递给catch
            // 如果没有发生异常catch代码块不执行
            //可以有多个catch语句,要求子类异常在后,子类异常在前
            e.printStackTrace();//在命令行打印异常信息在程序中出错的位置及原因
            System.out.println(e.getMessage());//输出异常信息
        }*//**//*finally{//如果没有finally,语法是通过的
            //不管try代码块是否有异常发生,始终要执行finally;所以,通常将释放资源,关闭链接的代码放在finally
        //也可以try-finally配合使用,这种方法相当于没有捕获异常,就是执行这块代码,不管有没有发生异常,都必须执行某个业务逻辑
            System.out.println("业务逻辑");
        }
        System.out.println("程序正常执行");*//*


    }
    public void test1() throws FileNotFoundException,NullPointerException {// throws 将发生的异常抛出,交给调用者来处理,最顶级的处理者是JVM
        //throws 后面的异常类型可以是方法中产生的异常处理,也可以是它的父类;后面也可以是异常列表
        FileInputStream one=new FileInputStream("d://aa.txt");
    }
}*/

/*class One{}
class Two extends One{}
class Three extends One{}
public class Demo2 {
    public static void main(String[] args) {
        One one=new Two();//向上转型
        Two two=(Two) one;//向下转型
        //Three three=(Three) two;//类型转换异常
        String name1="1234";
        int number1=Integer.parseInt(name1);//将字符串转化为数字
        System.out.println(number1);
String name2="阿伟学java";
        int number2=Integer.parseInt(name2);
        System.out.println(number2);//数字格式不正确异常


        //还有:空指针异常  数学运算异常 数组下标访问异常
    }
}*/
/*
 异常处理就是当异常发生时,对异常的处理方式

 编译异常,程序中必须处理 try-catch 或者 throws
 对于运行异常,程序中如果没有处理,默认就是throws的方式处理

 */
/*class Father{
    public void method() throws RuntimeException{

    }
}
class Son extends Father{
    //子类重写父类的方法时,所抛出的异常类型和父类抛出的异常一致,要么为父类抛出异常类型的子类型
    @Override
    public void method() throws NullPointerException {
        super.method();
    }
}*/

/*自定义异常  如果继承Exception 属于编译异常
throws  异常处理的一种方式    位置在方法声明处  后面跟异常类型
throw   手动生成异常的关键字   位置在方法体中   后面跟异常对象
如果抛出的是运行异常,则不要求程序员显示处理,因为有默认的处理机制(通常把自定义异常做成运行时异常)
 */
/*class One extends RuntimeException{
    public One(String message) {
        super(message);
    }
}
public class Demo2 {
    public static void main(String[] args) {
        int age=80;
        if(!(age>=0 &&age<=100)){
            throw new One("需要年龄在0-100之间");
        }
        System.out.println("你的年龄范围正确");
    }
}*/

/*  Throwable是 Java 语言中所有错误或异常的超类(Error  Exception(RuntimeException  ClassNotFoundException))
五大运行异常
1.NullPointerException 空指针异常

2.ArithmeticException 数学运算异常

3.ArrayIndexOutOfBoundException 数组下标越界异常

4.ClassCastException 类型转换异常

5.NumberFormatException 数字格式不正确异常[]
 */

/*
针对八种数据类型相应的引用类型--包装类(有了类的特点就可以调用类的方法)
boolean---> Boolean  char--->Character
其他六种包装类的父类是Number  byte--->Byte  short--->Short  int--->Integer long--->Long   float--->Float  double--->Double
 true?new Integer(1):new Double(2.0)  返回结果是1.0  要把三元运算符看做一个整体
 */
//public class Demo2 {
//
//    public static void main(String[] args) {
//        //jdk5以前需要手动装箱(基本->引用)
//        /*int number1=10;
//        Integer integer=new Integer(number1);//装箱1
//        Integer integer1=Integer.valueOf(number1);//装箱2
//        //拆箱(引用->基本)
//        int number2=integer.intValue();
//
//        // jdk5以后自动装箱
//        int number3=100;
//        Integer integer2=number3;
//        //拆箱
//        int number4=integer2;*/
//
//        //包装类(Integer)->String
//        /*Integer number1=100;
//        String str1=number1+"";//方式一
//        String str2=number1.toString();//方式二
//        String str3=String.valueOf(number1);//方式三
//        //String->包装类(Integer)
//        String str4="123";
//        Integer integer=Integer.parseInt(str4);//使用到自动装箱
//        Integer integer1=new Integer(str4);//构造器*/
//
//       /* System.out.println(Integer.MAX_VALUE);//返回最大值
//        System.out.println(Integer.MAX_VALUE);//返回最小值
//
//        System.out.println(Character.isDigit('a'));//判断是不是数字
//        System.out.println(Character.isLetter('a'));//判断是不是字母
//        System.out.println(Character.isUpperCase('a'));//判断是不是大写
//        System.out.println(Character.isLowerCase('a'));//判断是不是小写
//
//        System.out.println(Character.isWhitespace('a'));//判断是不是空格
//        System.out.println(Character.toUpperCase('a'));//转成大写
//        System.out.println(Character.toLowerCase('A'));//转成小写*/
//
//        //  == 基本类型,判断值是否相等
//
//        /*
//
//        字符串的字符使用Unicode字符编码,一个字符(不管是字母还是汉字)占两个字节
//        String 实现了Serializable,说明了字符串可以串行化(串行化:可以在网络传输);实现了Comparable,说明字符串可以比较
//        String是final类,不能被其他类继承
//
//         */
//        /*final char[] value={'a','b','c'};
String有属性 private final char value[] ; value[]用于存放字符串内容(value是final类型,不可以修改,即value不能指向新的地址,但是单个字符串内容是可以变化的)
//        value[0]='A';*/
//
//        /*//创建String对象的区别
//        String str1="hello";//方式一
//        //先看常量池是否有"hello"数据空间,有就直接指向;如果没有重新创建,str1指向常量池的空间地址
//        String str2=new String("hello");
//        //现在堆中创建空间,里面维护了value属性,指向常量池的"hello"空间,如果常量池没有"hello",重新创建;如果有,直接通过value指向*/
//
//        /*String str1="hello"+"Java";
//        //编译器不傻,做了优化 String str1="helloJava"; 只创建了一个对象*/
//
//        /*String str1="hello";
//        String str2="Java";
//        String str3=str1+str2;//最终str3指向堆中的对象(String) value[] -> 池中"helloJava"
//        String str4="helloJava";
//        System.out.println(str3==str4);//F*/
//
//       /* System.out.println("阿伟已经死了".length());//获取字符串的长度  6
//
//        // indexOf 获取字符在字符串第一次出现的索引,找不到返回-1
//        String str1="qq.com";
//        int index=str1.indexOf('.');//2
//        System.out.println(index);
//        System.out.println(str1.indexOf("co"));//3
//        str1="999@qq.com";
//        int index1=str1.lastIndexOf('@');
//        System.out.println(index1);//3
//
//        // substring 截取指定范围的字串
//        String name="罗罗诺亚·索隆";
//        System.out.println(name.substring(5));//从索引5的开始截取后面所有内容
//        System.out.println(name.substring(5,7));//索隆*/
//
//        /*String str1="heLLo";
//        System.out.println(str1.toUpperCase());//转大写
//        System.out.println(str1.toLowerCase());//转小写*/
//
//        //concat 拼接字符串
//        /*String str1="阿伟";
//        String str2=str1.concat("已经").concat("死了");
//        System.out.println(str1);
//        System.out.println(str2);*/
//
//        // replace 替换字符串字符
//        /*String say="你,已经死了,不要再找了";
//        String say1=say.replace("你","阿伟");
//        System.out.println(say);
//        System.out.println(say1);*/
//
//        //split 分割字符
//        /*String quatation="背后的伤痕是剑士的耻辱,索隆大大";
//        String[] array=quatation.split(",");
//        for(String string:array){//for(数据类型 变量名 :遍历的目标)
//            System.out.println(string);
//        }*/
//
//        // toCharArray 转换为字符数组
//        /*String str1="hello";
//        char[] chars=str1.toCharArray();
//        for(char char1:chars){
//            System.out.println(char1);
//        }*/
//
//        //  compareTo比较两个字符串的大小 长度相同,每个字符相等,返回0   长度不相等,前面字符相等,就返回两个字符串的差值
//        /*String str1="hel";
//        String str2="hello";
//        System.out.println(str1.compareTo(str2));  //-2*/
//
//        /*String name="阿伟";
//        char gender='男';
//        int age=18;
//        String str1=String.format("我叫%s,性别%c,年龄%d,希望大家可以喜欢我!",name,gender,age);
//        System.out.println(str1);
//        String str2="我叫%s,性别%c,年龄%d,希望大家可以喜欢我!";
//        String str3=String.format(str2,name,gender,age);
//        System.out.println(str3);
//        System.out.println(String.format(str2,name,gender,age));
//         // %.2f 保留小数点两位,并进行四舍五入的处理   占位符(这些占位由后面变量替换)*/
//
//        /*
//        // String类是保存字符串常量的,每次更新都需要重新开辟空间,效率较低
//        因此java设计者还提供了StringBuilder和StringBuffer来增强String功能,提高效率
//
//        StringBuffer代表可见的字符序列,可以对字符串内容进行增删(很多方法和String相同)
//        StringBuffer(是一个final类,不能被继承)直接父类AbstractStringBuilder(父类有属性 char[]value ,不是final ,value存放字符串内容,放在堆中)
//        StringBuffer实现了SeriaLizable(他的对象可以串行化)
//        StringBuffer保存的是字符串常量,里面的值不可更改,每次更新实际上更新内容,而不是地址
//         */
//
//        /*//1.创建一个大小为16的char[],用于存放字符内容
//        StringBuffer stringBuffer = new StringBuffer();
//        //2.通过构造器指定char[]大小
//        StringBuffer stringBuffer1=new StringBuffer(100);
//        //3.  char[]大小是 stringBuffer2.length()+16
//        StringBuffer stringBuffer2=new StringBuffer("hello");
//
//        // String->StringBuffer
//        String str="hello";
//        //方式一:构造器
//        StringBuffer stringBuffer3=new StringBuffer(str);
//        //方式二:使用append方法
//        StringBuffer stringBuffer4=new StringBuffer();
//        stringBuffer4=stringBuffer4.append(str);
//
//        //  StringBuffer-->String
//        StringBuffer stringBuffer5=new StringBuffer("阿伟学Java");
//        //方式一 使用StringBuffer提供的toString方法
//        String str1=stringBuffer5.toString();
//        //方式二 使用构造器来搞定
//        String str2=new String(stringBuffer5);*/
//
//        /*StringBuffer stringBuffer=new StringBuffer("hello");
//
//        //append增
//        stringBuffer.append(",");
//        stringBuffer.append(100);
//        stringBuffer.append(0.1);
//        System.out.println(stringBuffer);
//
//        //delete删 删除左闭右开
//        stringBuffer.delete(5,12);
//        System.out.println(stringBuffer);
//
//        //查 找不到返回-1
//        int indexOf=stringBuffer.indexOf("l");
//        System.out.println(indexOf);
//
//        //改 左闭右开
//        stringBuffer.replace(1,2,"aha");
//        System.out.println(stringBuffer);
//
//        //插入 在索引0的位置插入
//        stringBuffer.insert(0,"say:");
//        System.out.println(stringBuffer);
//
//        //长度
//        System.out.println(stringBuffer.length());*/
//
//        //打印价格的小数点前面每三位逗号隔开  3,542.88
//        /*String price="3542.88";
//        StringBuffer stringBuffer=new StringBuffer(price);
//        for(int i=stringBuffer.lastIndexOf(".")-3;i>0;i-=3){
//            stringBuffer.insert(i,",");
//        }
//        System.out.println(stringBuffer);*/
//
//        /*StringBuilder(最快) ,没有做互斥处理(没有synchronized关键字)因此在单线程的情况下使用(字符串存在大量修改操作,单线程使用这个)
//          StringBuffer(次之) ,线程安全(字符串存在大量修改操作,多线程使用这个)
//          String(最慢),效率低但复用性高(很少修改,被多个对象引用,比如配置信息用它)
//         */
//
//        //  Math基本数据运算的方法
//
//        //abs绝对值
//        /*System.out.println(Math.abs(-10));
//
//        //pow求幂
//        System.out.println(Math.pow(-2,3));
//
//        //ceil 向上取整
//        System.out.println(Math.ceil(-3.22));
//
//        //floor 向下取整
//        System.out.println(Math.floor(-3.21));
//
//        //round 四舍五入
//        System.out.println(Math.round(-3.54));
//
//        //sqrt 开平方
//        System.out.println(Math.sqrt(9.0));//负数 就会打印 NaN(not a number)
//
//        //random随机数 [0,1)的数字  (int)(a+Math.random()*(b-a+1))  打印2-7的数字  a就等于2,b等于7
//        for(int i=1;i<10;i++){
//            System.out.println((int)(2+Math.random()*(7-2+1)));
//        }
//
//        //max min 返回最大值最小值
//        System.out.println(Math.max(5,4));
//        System.out.println(Math.min(3,2));*/
//
//        // Arrays类包含了一系列静态方法
//
//       /* //1. toString返回数组的字符串形式
//        int[] array={1,4,3,6,5};
//        //System.out.println(Arrays.toString(array));
//
//        //2. sort自然排序和定制排序
//        Arrays.sort(array);// 自然排序  //数组是引用类型,通过sort排序后会影响实参
//        System.out.println(Arrays.toString(array));*/
//
//        //定制排序
//        /*Integer array[]={1,3,5,9,7};
//        Arrays.sort( array,new Comparator(){
//            @Override
//            public int compare(Object o1,Object o2){//  public int compare返回值大于零或等于零会影响排序效果
//                Integer number1=(Integer) o1;
//                Integer number2=(Integer) o2;
//                return number2-number1;
//            }
//        });
//        System.out.println(Arrays.toString(array));
//         */
//
//       /* int array[]={1,-1,8,0};
//        bubble(array, new Comparator() {
//            @Override
//            public int compare(Object o1, Object o2) {
//                int number1=(Integer)o1;
//                int number2=(Integer)o2;
//                return number1-number2;//升序
//            }
//        });
//        System.out.println(Arrays.toString(array));*/
//
//        /*// binarySearch二分查找  如果数组不存在该元素 就返回 -(low + 1)
//        Integer[] array={1, 2, 3,  7, 8, 9};//二分查找必须排好
//        int index= Arrays.binarySearch(array,4);
//        System.out.println("index="+index);
//
//        //  copyOf 在array数组中,拷贝array.length个元素到newArray
//        Integer[] newArray=Arrays.copyOf(array,array.length);
//        System.out.println(Arrays.toString(newArray));
//        Integer[] newArray1=Arrays.copyOf(array,array.length+1);//多一个元素为null
//        System.out.println(Arrays.toString(newArray));
//        Integer[] newArray2=Arrays.copyOf(array,array.length-1);//少拷贝一个元素
//        System.out.println(Arrays.toString(newArray));
//
//        //equals 比较数组两个元素是否相等
//        Integer[] array1={1,2,3,7,8};
//        boolean equals=Arrays.equals(array,array1);
//        System.out.println(equals);//数组元素一样返回true 否则false*/
//
//        /*//  asList将一组值转换为List集合
//        List asList= Arrays.asList(3,2,6,5,9,8);
//        System.out.println("asList="+asList);
//        System.out.println(asList.getClass());// asList运行内存class java.util.Arrays$ArrayList是Arrays类的静态内部类*/
//
//        Book[] books=new Book[3];
//        books[0]=new Book("肖申克的救赎",99.99);
//        books[1]=new Book("红楼梦",88.88);
//        books[2]=new Book("三体",110.11);
//
//        //按价格排序
//        /*Arrays.sort(books, new Comparator() {
//            @Override
//            public int compare(Object o1, Object o2) {
//                Book book1=(Book)o1;
//                Book book2=(Book)o2;
//                double sub=book2.getPrice()- book1.getPrice();
//                if(sub>0){
//                    return 1;
//                }
//                else if(sub<0){
//                    return -1;
//                }
//                else{
//                    return 0;
//                }
//            }
//        });*/
//
//        Arrays.sort(books, new Comparator<Book>() {
//            @Override
//            public int compare(Book o1, Book o2) {
//                Book book1=(Book) o1;
//                Book book2=(Book) o2;
//                return book2.getName().length()-book1.getName().length();
//
//            }
//        });
//
//        System.out.println(books[0]);
//        System.out.println(Arrays.toString(books));
//
//    }
//    public static void bubble(int[] array, Comparator c){
//        //冒泡+排序
//        int temp=0;
//        for(int i=0;i<array.length;i++){
//            for(int j=0;j<array.length-1;j++){
//                if(c.compare(array[j],array[j+1])>0){
//                    temp=array[j];
//                    array[j]=array[j+1];
//                    array[j+1]=temp;
//                }
//            }
//        }
//
//    }
//}
//
//class Book{
//    private String name;
//    private double price;
//
//    public Book(String name, double price) {
//        this.name = name;
//        this.price = price;
//    }
//
//    public String getName() {
//        return name;
//    }
//
//    public void setName(String name) {
//        this.name = name;
//    }
//
//    public double getPrice() {
//        return price;
//    }
//
//    public void setPrice(double price) {
//        this.price = price;
//    }
//
//    @Override
//    public String toString() {
//        return "Book{" +
//                "name='" + name + '\'' +
//                ", price=" + price +
//                '}';
//    }
//}

/*import java.text.ParseException;

//@SuppressWarnings("all")
public class Demo2 {
    public static void main(String[] args) throws ParseException {*/
        //System类的常见方法

        //exit退出当前程序
        /*System.out.println("1");
        System.exit(0); //  exit(0) 表示程序退出,0表示正常的状态
        System.out.println("2");*/

        //arraycopy复制数组元素
       /* int[] array={1, 2, 3};
        int[] array1=new int[3];
        System.arraycopy(array,0,array1,0,2); // array源数组  0:源数组索引值  array1目标数组  0:目标索引  3:拷贝长度
        System.out.println("array1="+ Arrays.toString(array1));*/

        //System.gc();运行垃圾回收机制

        //currentTimeMillis() 返回当前时间距离1970-1-1的毫秒数
        //System.out.println(System.currentTimeMillis());

        //BigInteger适合保存较大的整形  BigDecimal适合保存精度更高的浮点型(小数)
        /*BigInteger bigInteger=new BigInteger("589999999999999999999999999999999999999999999999999");
        BigInteger bigInteger1=new BigInteger("1");
        System.out.println(bigInteger);
        //在对BigInteger进行加减乘除,需要使用相应的方法,不能直接进行 + - * /
        BigInteger add=bigInteger.add(bigInteger1);
        System.out.println(add);
        BigInteger subtract=bigInteger.subtract(bigInteger1);
        System.out.println(subtract);
        BigInteger multiply=bigInteger.multiply(bigInteger1);
        System.out.println(multiply);
        BigInteger divide=bigInteger.divide(bigInteger1);
        System.out.println(divide);*/

        /*BigDecimal bigDecimal=new BigDecimal("1.999999999999999999999999999999999999999999999998");
        System.out.println(bigDecimal);
        BigDecimal bigDecimal1=new BigDecimal(0.2);
        System.out.println(bigDecimal.add(bigDecimal1));
        System.out.println(bigDecimal.subtract(bigDecimal1));
        System.out.println(bigDecimal.multiply(bigDecimal1));

        //System.out.println(bigDecimal.divide(bigDecimal1));// 可能抛出异常  bigDecimal对应精度太高,除不尽
        System.out.println(bigDecimal.divide(bigDecimal1,BigDecimal.ROUND_CEILING));//如果有无限循环的小数,就会保留分子的精度
        System.out.println(bigDecimal.divide(bigDecimal1));*/

       /* //第一代日期类  JDK1.0包含了Date类,但它的大多数方法已经在JDK1.1中引用
        Date date=new Date();//获取当前系统时间
        System.out.println("当前日期="+date);//默认输出的日期格式是国外的格式,因此通常需要对格式进行转换
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");//指定相应的日期格式
        String format=sdf.format(date);// format将日期转换成指定格式的字符串
        System.out.println("当前日期="+format);

        //可以把格式化的String,转化为Date
        String str="1998年01月01日 10:10:10 星期四";
        Date parse=sdf.parse(str);//使用的std格式需要你给的String的格式一样,否则会抛出异常
        System.out.println(sdf.format(parse));*/

        /*//第二代日期类 Calendar是一个抽象类,构造器是private 可以通过getInstance来获取实例
        Calendar calendar=Calendar.getInstance();  //创建日历对象 比较简单自由
        System.out.println(calendar);
        System.out.println("年:"+calendar.get(Calendar.YEAR));
        System.out.println("月:"+calendar.get(Calendar.MONTH));
        System.out.println("日:"+calendar.get(Calendar.DAY_OF_MONTH));
        System.out.println("小时:"+calendar.get(Calendar.HOUR));
        System.out.println("分钟:"+calendar.get(Calendar.MINUTE));
        System.out.println("每秒:"+calendar.get(Calendar.SECOND));
        // Calendar没有专门格式化的方法,所以需要程序员自己来组合
        System.out.println(calendar.get(Calendar.YEAR)+"年"+calendar.get(Calendar.MONTH)+"月"+calendar.get(Calendar.DAY_OF_MONTH)+"日");
        //如果我们需要24进制来获取时间 Calendar.MOTH  改成 Calendar.HOUR_OF_DAY
        System.out.println("小时:"+calendar.get(Calendar.HOUR_OF_DAY));*/

        /*前两代不足分析:
        可变性:日期和时间这样的类应该不可变的
        偏移性:Date中的年份从1900开始,而月份是从0开始的
        格式化:格式化只对Date有用,Calendar则不行
        此外:他们还有线性安全

        //第三代日期常见方法 LocalDate(日期)   LocalTime(时间)   LocalDateTime(日期+时间) JDk8加入
         */
       /* LocalDateTime ldt=LocalDateTime.now();//  now()返回当前的日期和对象
        System.out.println(ldt);
        //使用DateTimeFormatter对象进行格式化
        DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format=dateTimeFormatter.format(ldt);
        System.out.println("格式化日期"+format);

        System.out.println("年"+ldt.getYear());
        System.out.println("月"+ldt.getMonth());
        System.out.println("日"+ldt.getDayOfMonth());
        System.out.println("时"+ldt.getHour());
        System.out.println("分"+ldt.getMinute());
        System.out.println("秒"+ldt.getSecond());

        //通过plus 和 minus方法可以对当前时间进行加和减
        LocalDateTime localDateTime=ldt.plusDays(365);//  365天后是什么时候
        System.out.println("365天后ldt值为"+dateTimeFormatter.format(localDateTime));
        LocalDateTime localDateTime1=ldt.minusDays(365); // 365天前是什么时候
        System.out.println("365天后ldt值为"+dateTimeFormatter.format(localDateTime1));*/


       /* //instant 时间戳
        Instant now =Instant.now();//通过静态now获取当前时间戳的对象
        System.out.println(now);
        //通过from可以把Instant转成Date
        Date date=Date.from(now);
        System.out.println(date);
        //通过date的toInstant()可以把date转换为Instant对象
        Instant instant=date.toInstant();
        System.out.println(instant);*/

        //将字符串部分进行反转

        /*String str=null;
        try {
            str = reverse(str, 1, 5);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return;
        }
        System.out.println("==交换前==");
        System.out.println(str);
        System.out.println("==交换后==");
        System.out.println(str);*/

      /*  //输入用户名,密码,邮箱,若果格式正确则提示注册成功,否则生成异常
        String name="awei";
        String password="123456";
        String email="aweo@qq.com";
        try {
            user(name,password,email);
            System.out.println("恭喜你,注册成功~");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }


    }
    public static String reverse(String str,int start,int end){
        if(!(str!=null&&start>=0&&end>start&&end<str.length())){//验证 写出正确的然后取反 过关斩将
            throw new RuntimeException("参数不正确");
        }
        char[] chars=str.toCharArray();
        char temp=' ';
        for(int i=start,j=end;i<j;i++,j--){
            temp=chars[i];
            chars[i]=chars[j];
            chars[j]=temp;
        }
        return new String(chars);//使用chars重新构建String返回即可
    }
    public static void user(String name,String password,String email){
        if(!(name!=null&&password!=null&&email!=null)){
            throw new RuntimeException("参数不能为null");
        }
        //第一关
        if(!(name.length()>=2&&name.length()<=4)){
            throw new RuntimeException("用户名长度为2-4");
        }
        //第二关
        if(!(password.length()==6&&isDigital(password))){
            throw new RuntimeException("密码长度为6,并且是数字");
        }
        //第三关
        int index=email.indexOf('@');
        int index1=email.indexOf('.');
        if(!(index>0&&index1>index)){
            throw new RuntimeException("邮箱需要有 @ 和 . ");
        }
    }
    public static boolean isDigital(String str){
        char[] chars=str.toCharArray();
        for (int i = 0; i <chars.length ; i++) {
            if(chars[i]<'0'||chars[i]>'9'){
                return false;
            }
        }
        return true;
    }
}
*/
    //数组:长度开始时必须指定,而且一旦指定,不能修改,保存的必须是同一类型-->集合
/*public class Demo2 {
    public static void main(String[] args) {*/
        //集合分为两种 (单列集合和双列集合) List Set 接口实现子类是单列集合   Map接口实现子类是双列集合
        /*ArrayList arrayList =new ArrayList();
        arrayList.add("jack");
        arrayList.add("tom");

        HashMap hashMap=new HashMap();
        hashMap.put("N1","haha");
        hashMap.put("N2","hehe");*/

        /*List list=new ArrayList();
        list.add("awei");
        list.add(10);//相当于 list.add(new Integer(10))
        list.add(true);
        System.out.println(list);
        //remove 删除指定元素
        //list.remove(0);//索引值删除
        list.remove("awei");//元素删除
        System.out.println(list);
        //contains:查找元素是否存在
        System.out.println(list.contains("awei"));//不存在false
        //size获取元素个数
        System.out.println(list.size());
        //isEmpty 判断是否为空
        System.out.println(list.isEmpty());//F
        */
        /*//clear 清空
       list.clear();
        System.out.println(list);
        //addAll 添加多个元素
        ArrayList list1=new ArrayList();
        list1.add("haha");
        list1.add("hehe");
        list.addAll(list1);
        System.out.println(list);
        //containsAll 查找多个元素是否都存在
        System.out.println(list.containsAll(list1));//T
        //removeAll 删除多个元素
        list.removeAll(list1);
        System.out.println(list);*/

        /*Iterator(迭代器) 主要遍历Collection集合中的元素
        所有实现Collection接口的集合都有一个iterator()方法,用于返回一个实现了Iterator接口的对象,即返回一个迭代器
        迭代器的执行原理:   hasNext()//判断是否还有下一个元素   next()//指针下移到下一个集合位置
        在调用it.next()方法之前必须调用it.hasNext()进行检测,若不调用,并且下一条记录无效,直接调用it.next()会抛出异常
         */

       /* Collection collection=new ArrayList();
        collection.add(new Book("红楼梦",55.55));
        collection.add(new Book("水浒传",66.66));
        //System.out.println(collection);
        //遍历collection集合
        // 1.先找到collection对应的迭代器
        Iterator iterator =collection.iterator();
        // 2.使用while循环遍历
        while (iterator.hasNext()) {//判断是否还有数据    生成while快捷键 itit   显示所有快捷键 ctrl + j
            Object next =  iterator.next();//返回下一个元素,类型是Object
            System.out.println(collection);
        }
        //3.当退出while循环 这时iterator迭代器指向最后一个元素
        //iterator.next();
        //4.如果再次遍历 需要重置我们的迭代器
        iterator =collection.iterator();
        while(iterator.hasNext()){
            Object obj=iterator.next();
            System.out.println(obj);
        }*/
/*
        //增强for(底层仍然是迭代器)循环就是简化版的iterator,本质一样,只能用于遍历数组和集合  快捷方式I
        List list=new ArrayList();//ArrayList线程不安全(执行效率高)
        list.add("haha");
        list.add("hehe");
        System.out.println(list);
        //list 集合每个元素都有对应的索引,即支持索引
        System.out.println(list.get(0));
        //在索引1处插入对象 nihao
        list.add(1,"nihao");
        System.out.println(list);

        List list1=new ArrayList();
        list1.add("baga");
        list1.add("baba");
        //把list1的对象全部加到list
        list.addAll(1,list1);
        System.out.println(list);
        list1.addAll(1,list);

        //返回obj在当前集合首次出现的位置
        System.out.println(list.indexOf("haha"));

        list.add("haha");
        System.out.println(list.lastIndexOf("haha"));

        //移除index位置的元素,并返回元素
        list.remove(0);
        System.out.println(list);

        //替换index的元素
        list.set(0,"haha");
        System.out.println(list);

        //返回子集合 左闭右开
        List returnList=list.subList(0,2);
        System.out.println(returnList);

        //遍历ArrayList  LinkedList Vector
        for (int i=0;i<list.size();i++) {
            *//*Object object=list.get(i);
            System.out.println(object);*//*
            System.out.println(list.get(i));
        }

        list.add(null);//可以存放空指针
        System.out.println(list);*/

        /*
        ArrayList是由数组来实现数据存储的  如果使用无参构造器,则初始elementDate容量为0(jdk7是10);
        添加元素先看是否需要扩容,需要则调用grow方法  第一次扩容是10,再次扩容每次是1.5倍

        new ArrayList(100) 如果使用有参构造器,初始为100,后面扩容每次是1.5倍

        transient 表示瞬间,短暂的,表示该属性不会被序列号   //一个序列化后的对象 可以被写到数据库或文件中,也可用于 网络传输

        Vector底层也是一个对象数组(线程同步即线程安全) 如果无参,默认10,满后按两倍扩容  指定大小也是后面两倍扩容

        LinkedList(线程不安全)底层维护了一个双向列表 维护了两个属性first(指向首节点)和last(指向尾节点)
        每个节点又维护了prev(指向前一个节点) next(指向后一个节点) item三个属性 最终实现了双向链表
        LinkedList的元素添加和删除,不是通过数组完成,相对来说效率较高

         */

        /*//模拟实现一个简单的双向链表
        Node jack=new Node("jack");
        Node tom=new Node("tom");
        Node awei=new Node("awei");
        //连接3个节点,形成双向链表 jack->tom->awei
        jack.next=tom;
        tom.next=awei;
        //awei->tom->jack
        awei.prev =tom;
        tom.prev =jack;

        Node first=jack;//让first引用指向jack;就是双向链表的头节点
        Node last=awei;//让last引用指向awei,这就是双向链表的尾节点

        //从头到尾遍历
        while(true){
            if(first==null){
                break;
            }
            //输出first信息
            System.out.println(first);
            first=first.next;
        }
        //从尾到头遍历
        *//*while(true){
            if(last==null){
                break;
            }
            System.out.println(last);
            last=last.prev;
        }*//*

        //创建一个节点
        Node laoliu=new Node("laoliu");
        laoliu.next=awei;
        laoliu.prev=tom;
        tom.next=laoliu;
        awei.prev=laoliu;

        //让first再次指向jack
        System.out.println("============");
        first=jack;
        while(true){
            if(first==null){
                break;
            }
            System.out.println(first);
            first=first.next;
        }*/

       /* LinkedList linkedList=new LinkedList();
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        System.out.println(linkedList);

        //删除一个节点
        linkedList.remove();//默认删除第一个
        System.out.println(linkedList);
        linkedList.remove(1);
        System.out.println(linkedList);

        //修改某个节点对象
        linkedList.set(0,99);
        System.out.println(linkedList);

        //得到某个节点对象  get()
        System.out.println(linkedList.get(0));

        linkedList.add(55);
        linkedList.add(44);
        //因为LinkedList实现了List接口,遍历方式也有三种
        System.out.println("==================");
        Iterator iterator=linkedList.iterator();

        while(iterator.hasNext()){
            Object obj=iterator.next();
            System.out.println(obj);
        }

        System.out.println("==================");
        for(Object o1:linkedList){
            System.out.println(o1);
        }

        System.out.println("==================");
        for(int i=0;i<linkedList.size();i++){
            System.out.println(linkedList.get(i));
        }*/

        //增删操作多选择LinkedList   查该操作多选择ArrayList(查改效率比较高)

        /*
        Set接口基本介绍 无序(添加和取出的顺序不一样),没有索引 不允许有重复的元素,最多包含一个null
        跟List接口一样,Set接口也是Collection的子接口,因此常用方法和Collection一样(不能用索引的方式来遍历数组)
         */
        /*Set set=new HashSet();
        set.add("jack");
        set.add("hello");
        set.add("jack");//只会显示一次
        set.add("haha");
        System.out.println(set);
        set.remove("hello");//删除
        System.out.println(set);

        //迭代器
        Iterator iterator=set.iterator();
        while(iterator.hasNext()){
            Object obj=iterator.next();
            System.out.println(obj);
        }
        System.out.println("======");
        for(Object obj:set){
            System.out.println(obj);
        }*/

        // HashSet(实际上是HashMap)实现了set接口  可以存放null值(但只能有一个) 不能有重复元素
        // HashSet底层是HashMap 添加一个元素,先得到hash值,会转成索引值  找到存储数据表table,看这个索引位置是否已经存在元素
        //如果没有直接加入,如果有,调用equals比较,如果相同就放弃添加,不同则添加到最后
        //HashSet第一次添加,数组table扩容到16,临界值是16*0.75  如果数组使用到了临界值12,则就会扩容到32,新的临界值32*0.75
        //在Java8中,如果一个链条的元素个数是8,并且table>=64,就会进行树化(红黑树),否则仍然采用数组扩容机制
        //HashMap底层是数组+链表+红黑树
       /* Set hashSet=new HashSet();
        hashSet.add(null);
        hashSet.add(null);
        hashSet.add(123);
        System.out.println(hashSet);
        System.out.println(hashSet.add("join"));//在执行add方法后,会返回一个boolean值 添加成功true
        System.out.println(hashSet.add(123));//F

        hashSet.remove("null");
        System.out.println(hashSet);

        //经典面试题
        System.out.println(hashSet.add(new String("haha")));//T
        System.out.println(hashSet.add(new String("haha")));//F*/

        // 调试debug  就完了
        /*Node1[] table=new Node1[16];//数组类型是Node1[]   有些人直接把Node[]数组称为表
        System.out.println(table);
        Node1 aWei=new Node1("aWei",null);
        table[2]=aWei;
        Node1 rose=new Node1("rose",null);
        aWei.next=rose;//将rose节点挂载到aWei
        Node1 jack=new Node1("jack",null);
        System.out.println(table);*/

        //定义一个Person类,当name和age的值相等,认为是相同的类,不能添加到HashSet集合中
        /*Set set=new HashSet();
        set.add(new Person("haha",18));
        set.add(new Person("haha",19));
        set.add(new Person("haha",18));
        System.out.println(set);*/

        //LinkedHashSet(底层是一个LinkHashMap 底层维护了一个数组(hash表)+双向链表(head和tail))是HashSet的子类  同时也不允许添加元素  遍历LinkedHashSet也能确保插入顺序和遍历顺序一样
        //第一次添加时,数组扩容到16 ,数组是HashMap$Node[] 存放节点类型/存放的元素LinkedHashMap$Entry

        /*
           JDk8 Map接口特点 用于保存具有映射关系的数据Key(不可以重复)-Value(可以重复)
           Map中的key和value可以是任何应用数据的类型,会封装到HashMap$Node对象中(HashMap$Node存放到entrySet就方便我们便利,因为Map.Entry提供了重要方法 K-getKey() V-getValue() )
           k-v为了方便遍历,还会创建EntrySet集合,该集合存放的元素类型Entry,而一个Entry对象就有一个k-v

           Map接口常用的实现类:HashMap(是Map接口频率使用最高的,线程不安全)  Hashtable 和Properties
         */
       /* Map map=new HashMap();
        map.put("first","古力娜扎");//常用String类作为Map的key
        map.put("first","马儿扎哈");//当有相同的key 就等价于替换
        map.put(null,null);
        map.put(null,"hello");//  key为null只能有一个 value为null可以为多个
        map.put("second","雷霆嘎巴");*/
       /* System.out.println(map);
      //  System.out.println(map.get(null));// 通过get方法,传入key,会返回对应的value
        //remove 根据键删除映射关系
        map.remove("first");
        System.out.println(map);
        //size 获取元素个数
        System.out.println(map.size());
        //isEmpty:判断个数是否为零
        System.out.println(map.isEmpty());//F
        //containsKey 查找键是否存在
        System.out.println(map.containsKey("awei"));//F
        //clear 清楚k-v
        map.clear();
        System.out.println(map);*/

        //Map接口遍历方法
        /*//1.先取出所有的Key 通过key 取出对应的Value
        Set keyset=map.keySet();//获取所有键
        //增强for
        for(Object key:keyset){
            System.out.println(key+"-"+map.get(key));
        }
        //迭代器
        System.out.println("-----------");
        Iterator iterator=keyset.iterator();
        while(iterator.hasNext()){
            Object key=iterator.next();
            System.out.println(key+"-"+map.get(key));
        }*/
        /*//2.把所有的values取出
        Collection values=map.values();
        for (Object value :values) {
            System.out.println(value);
        }
        System.out.println("-------------");
        //迭代器
        Iterator iterator=values.iterator();
        while(iterator.hasNext()){
            Object value=iterator.next();
            System.out.println(value);
        }*/
        //3.通过EntrySet 来获取k-v
      /*  Set entrySet=map.entrySet();
        for (Object entry :entrySet) {
            //将entry转换Map.Entry
            Map.Entry map1=(Map.Entry)entry;
            System.out.println(map1.getKey()+"-"+map1.getValue());
        }
        //迭代器
        System.out.println("--------------");
        Iterator iterator=entrySet.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            //System.out.println(next.getClass());//HashMap$Node实现Map.Entry(getKey getValue)
            Map.Entry map2=(Map.Entry)next;
            System.out.println(map2.getKey()+"-"+map2.getValue());
        }*/

      /*  Map hashMap=new HashMap();
        //添加对象
        hashMap.put(1,new Person("awei",18222));
        hashMap.put(2,new Person("rose",17222));
        hashMap.put(3,new Person("jack",19222));
        //遍历一
        Set keySet=hashMap.keySet();
        for (Object key :keySet) {
            Person person=(Person)hashMap.get(key);
            if(person.getPrice()>18000){
                System.out.println(person);
            }
        }
        //遍历二
        Set entrySet=hashMap.entrySet();
        Iterator iterator= entrySet.iterator();
        while(iterator.hasNext()){
            Map.Entry entry=(Map.Entry)iterator.next();
            Person person=(Person)entry.getValue();
            if(person.getPrice()>18000){
                System.out.println(person);
            }
        }
*/
        /*JDK7 hashMap(底层维护了Node类型的数组table)实现了数组+链表  JDK8实现了数组+链表+红黑树
        当创建对象时,加载因子是0.75  添加对象,通过key哈希值得到在table的索引,然后是否判断索引是否有该元素,有元素则判断是否和加入的元素相等
        相等直接替换,如果不相等则判断树结构还是链表结构,做出相应处理,容量不够就会扩容(第一次默认16)(后面扩容为原容量的两倍)

        HashTable存放的元素键值对 K-V 键和值都不能为null ;  线程是安全的(效率较低) ;HashMap(效率高)线程不安全;初始大小为11;乘2加1扩容

        Properties类继承Hashtable并实现了Map,也是使用一种健值的形式来存储数据  还可以读取和修改xxx.properties文件
        如果有相同的key,value被替换
         */
      /*  Properties properties=new Properties();
        properties.put("jack",100);//  k-v
        //properties.put(null,88);//空指针异常
        properties.put("smith",200);
        properties.put("awei",300);
        System.out.println(properties);
        System.out.println(properties.get("awei"));
        //删除
        properties.remove("smith");
        System.out.println(properties);
*/

        /*
        如何选择集合 先判断存储类型(一组对象或一组健值)

        一组对象:Collection接口
        允许重复List(增删多LinkedList底层维护了一个双向链表   改查多ArrayList底层维护了一个Object可变数组)
        不允许重复Set(无序HashSet 数组+链表+红黑树底层HashMap,维护了一个哈希表  排序TreeSet)  插入和取出顺序一致LinkedHashSet维护数组+双向链表

        一组健值: Map
        健无序(HashMap底层哈希表 jdk7数组+链表 jdk8数组+链表+红黑树)
        健排序(TreeMap)
        健插入和取出一致:LinkedHashMap
        读取文件Properties

         */

        //TreeSet treeSet=new TreeSet();//无参构造创建TreeSet,仍然无需
        /*TreeSet treeSet=new TreeSet(new Comparator() {

            @Override
            public int compare(Object o1, Object o2) {
                //调用String的compareTo方法进行字符串大小比较
                //return ((String)o1).compareTo((String)o2);

                //加入的元素按照长度大小排序
                return ((String)o1).length()-((String)o2).length();
            }
        });
        treeSet.add("haha");
        treeSet.add("ehe");
        treeSet.add("nihao");
        System.out.println(treeSet);*/


        //TreeMap treeMap=new TreeMap();//TreeMap 使用无参构造器,也是无序的
       /* TreeMap treeMap=new TreeMap(new Comparator(){

            @Override
            public int compare(Object o1, Object o2) {
                //调用String的compareTo方法进行字符串大小比较
                //return ((String)o1).compareTo((String)o2);

                //加入的元素按照长度大小排序
                return ((String)o1).length()-((String)o2).length();
            }
        });
        treeMap.put("jac","haha");
        treeMap.put("rose","gaga");
        treeMap.put("ji","nihao");
        System.out.println(treeMap);*/

        //Collections工具类 是一个操作Set,List和Map等集合的工具类 提供了一序列的静态方法

       /* List list=new ArrayList();
        list.add("hahaha");
        list.add("rose");
        list.add("O");
        list.add("gun");
        list.add("gun");

        //反转List中元素的顺序
        Collections.reverse(list);
        System.out.println(list);
        //根据元素的自然顺序对指定List进行升序操作
        Collections.sort(list);
        System.out.println(list);
        //按照字符串大小长度排序
        Collections.sort(list,new Comparator(){

            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length();
            }
        });
        //指定元素进行交换swap(list,int,int)
        Collections.swap(list,0,1);
        //根据元素的自然顺序,返回集合的最大元素
        System.out.println(Collections.max(list));
        //根据指定的顺序,返回最大的元素
        Object max=Collections.max(list,new Comparator(){

            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length();
            }
        });
        System.out.println(max);

        //  Object min(Collection)  Objection(Collection,Comparator)

        //返回指定元素出现的次数
        System.out.println(Collections.frequency(list,"gun"));

        ArrayList one=new ArrayList();
        for(int i=0;i<list.size();i++){
            one.add("");
        }
        //copy拷贝 需要两个集合size一样
        Collections.copy(one,list);
        System.out.println(one);
        //新值换旧值
        Collections.replaceAll(list,"gun","哦哦");
        System.out.println(list);*/


        /*
        HashSet和TreeSet去重机制
        HashSet:hashCode()+equals()先通过存入对象,进行运算得到hash值,通过hash值找到索引,如果table索引所在的位置
                    ,没有数据,直接存放,如果有数据就进行equals遍历比较,比较后不相同添加,相同不添加
        TreeSet:如果你传入了一个Comparator匿名对象,就使用实现的comparator去重,如果方法返回0,就认为是相同的元素,就不添加
                    ,如果你没有传入Comparator匿名对象,则你添加的对象实现Comparable接口的compareTo去重

         */
      /*  TreeSet treeSet=new TreeSet();
        // TreeSet()构造器没有传入Comparator接口的匿名内部类  所以底层就把Person转换Comparable类型
        treeSet.add(new Person());//ClassCastException  类强制转换异常*/
/*    }
}*/
//class Person{}
/*class Person implements Comparable{

    @Override
    public int compareTo(Object o) {
        return 0;//如果方法返回0,就认为是相同的元素,就不添加
    }
}*/
/*class Book{
    private String name;
    private double price;

    public Book(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

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

class Node{
    public Object item;//真正存放的数据
    public Node next;//指向后一个节点
    public Node prev;//指向前一个节点
    public Node(Object name){
        this.item=name;
    }

    @Override
    public String toString() {
        return "Node{" +
                "name=" + item +
                '}';
    }
}*/
/*
class Node1{//节点 存储数据 可以指向下一个节点
    Object item;//存放数据
    Node1 next;//指向下一个节点

    public Node1(Object item, Node1 next) {
        this.item = item;
        this.next = next;
    }

    public Object getItem() {
        return item;
    }

    public void setItem(Object item) {
        this.item = item;
    }

    public Node1 getNext() {
        return next;
    }

    public void setNext(Node1 next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node1{" +
                "item=" + item +
                ", next=" + next +
                '}';
    }
}

*/

/*class Person{
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}*/

/*class Person{//使用HashMap添加三个对象,并遍历大于18000的员工
    private String name;
    private double price;

    public Person(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}*/











666 



/**
 * @author 耿世伟
 * @version 1.0
 */
/*public class Demo3 {
    *//*
  传统方法不能对ArrayList中的数据类型进行约束(不安全)
  遍历的时候需要进行类型转换,如果数据特变多,就会影响效率

  泛型(广泛的类型==>Integer,String等  Jdk5出现的)好处:编译的时候,检查元素类型,提高了安全性;减少了类型转换次数,提高了效率
Java泛型可以保证如果程序在编译时没有警告,运行时就不会发生ClassCastException异常 同时代码更加简洁,健壮
    泛型的类型是在创建对象时确定的(因为创建对象,需要指定确定类型)
     *//*
    public static void main(String[] args) {*/

       /* //ArrayList<Dog>表示存放ArrayList集合中的元素是Dog类型
        ArrayList<Dog> arrayList=new ArrayList<Dog>();
        arrayList.add(new Dog("旺财",18));
        arrayList.add(new Dog("进宝",19));
        //遍历的时候,直接取出Dog类型而不是Object
        for(Dog dog:arrayList){
            //不使用泛型 存放先转换成Object 再取出时还要转换成Dog
            System.out.println(dog.getName()+"+"+dog.getAge());
        }*/

        //给泛型指定数据类型,要求是引用类型,而不是基本数据类型
        /*Person<String> person=new Person<String>("招财");
        Person<Integer> person1=new Person<Integer>(001);*/

        /*//给泛型指定具体类型后,可以传入该类型或者子类型
        Word<A> one=new Word<A>(new A());// A不代表值,而是类型 任何字母都可以,通常是T,是Type的缩写
        Word<A> two=new Word<A>(new B());
        //在实际开发中 也可以简写 编译器会进行类型推断
        Word<A> two1=new Word<>(new B());*/

      /*  ArrayList arrayList=new ArrayList();
        //在创建对象,没有指定类型,默认Object
        //等价于  ArrayList<Object> arrayList=new ArrayList<>();*/

/*        List<Object> list1=new ArrayList<>();
        List<String> list2=new ArrayList<>();
        List<AA> list3=new ArrayList<>();
        List<BB> list4=new ArrayList<>();
        List<CC> list5=new ArrayList<>();

        //--------------------------
        test(list1);
        test(list2);
        test(list3);
        test(list4);
        test(list5);
        //----------------------------
        *//*test1(list1);
        test1(list2);*//*
        test1(list3);
        test1(list4);
        test1(list5);
        //----------------------------
        test2(list1);
        //test2(list2);
        test2(list3);
        *//*test2(list4);
        test2(list5);*//*

    }
    public static void test(List<?>c){//支持任意泛型类型

    }
    public static void test1(List<?extends AA>c){//支持AA及AA的子类

    }
    public static void test2(List<?super AA>c){//支持AA及AA的父类

    }

}*/
/*class AA{}
class BB extends AA{}
class CC extends BB{}*/

/*//Cat后面泛型 我们就把Cat称为自定义泛型
class Cat<A,B,C>{// A B C泛型标识符,一般是单个字母大写  泛型可以有很多个  泛型类
    String name;
    A a;
   // static A a1;  静态和类相关,在类加载时,对象还没创建,静态方法使用泛型,JVM无法初始化,所以会报错
   // 静态方法也不能使用泛型
    B b;
    C c;
    A[] array;//泛型的数组不能被初始化 因为是泛型,不能确定A的类型,不知道要开辟多大空间

    public <T,R>void hi(T t,A a){//泛型方法

    }
    public void say(B b){//不是泛型方法 而是使用了泛型
        //泛型方法,可以定义在普通类中,也可以定义在泛型类
        //当泛型方法被调用 类型会确定
    }
}*/

/*//自定义泛型接口
interface A<B,C>{

}
//在继承接口 指定泛型接口的类型
interface A1 extends A<String,Integer>{
}
//在实现接口  指定泛型接口的类型  没有指定默认Object
class A2 implements A<Float,Double>{
}*/

/*class A{
    public A() {
    }
}
class B extends A{};
class Word<E>{
    E e;

    public Word(A a) {
    }
}*/

/*class Dog{
    private String name;
    private int age;

    public Dog(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;
    }
}*/

/*class Person<E>{//泛型作用 可以在类声明时

    E name;//通过一个标识表示类中某个属性  该类型在定义Person类型指定

    public Person(E name) {//通过一个标识表示类中参数类型
        this.name = name;
    }

    public E getName() {//通过一个标识表示类中方法的返回值类型
        return name;
    }

    public void setName(E name) {
        this.name = name;
    }
}*/


//一个类中有很多代码需要测试 为了测试需要写在main方法中  多次代码测试就需要来回注销,切换很麻烦
//如果可以直接运行一个方法,并给出相关信息,就好了  ------> JUnit

/*public class Demo3{

    @Test
    public void my(){
        System.out.println(1+1);
    }
}*/

/*
 java绘图坐标系
 像素是一个密度单位  而厘米是一个长度单位
 */
/*public class Demo3 extends JFrame{// JFrame 对应窗口 可以理解为一个画框
    //定义一个面板
    private MyPhoto mp=null;
    public static void main(String[] args) {
       new Demo3();
    }
    public Demo3(){//构造器
        //初始化面板
        mp=new MyPhoto();
        //把面板放到窗口
        this.add(mp);
        //设置窗口大小
        this.setSize(400,300);
        this.setVisible(true);//可以显示
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//当点击窗口的X,程序完全退出
    }
}

//先定义一个MyPhoto(相当于画笔),继承JPanel
class MyPhoto extends JPanel {
    @Override
    public void paint(Graphics g) {//绘图方法  //paint(Graphics g)  绘制组件
        // Graphics(提供很多绘图方法) g(画笔)

        super.paint(g);//调用父类完成初始化
        //画一个圆形
        //System.out.println("paint被执行");
        //当程序第一次运行时,窗口最大化和最小化,repaint()刷新组件外观  程序会自动调用paint()方法来绘制组件

        //画椭圆边框
        //g.drawOval(10,10,100,100);//前俩参数椭圆的左上角坐标  第三个参数宽度  第四个参数高度

        //画直线
        //g.drawLine(10,10,200,200);//前俩参数起点  后俩参数终点

        //画矩形边框
        //g.drawRect(10,10,50,50);//前俩参数矩形的左上角坐标  第三个参数宽度  第四个参数高度

        //填充矩形
        //g.setColor(Color.BLACK);//先设置画笔颜色
        //g.fillRect(10,10,50,50);//前俩参数矩形的左上角坐标  第三个参数宽度  第四个参数高度

        //填充椭圆
        //g.setColor(Color.BLACK);//先设置画笔颜色
        //g.fillOval(10,10,50,50);//前俩参数椭圆的左上角坐标  第三个参数宽度  第四个参数高度

        //画字符串
        g.setColor(Color.BLACK);//设置颜色
        g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体
        g.drawString("主线任务:夺回秋雅",0,50);//这里设置的坐标是左下角
    }
}*/

//java事件处理机制 委派事件模型 当事件(键盘事件,鼠标事件,窗口事件)发生,产生事件对象,会把信息传递给事件监听者来处理
/*
public class Demo3 extends JFrame {
    MyPanel mp=null;
    public static void main(String[] args) {
        new Demo3();
    }
    public Demo3(){
        mp=new MyPanel();
        this.add(mp);
        this.setSize(400,300);
        this.addKeyListener(mp);//窗口JFrame对象可以对键盘进行监听
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
}

//画板  画出小球
//(MyPanel)事件监听者是一个类  它实现了KeyListener接口 他就可以作为一个事件监听者 对接收到的信息进行处理
class MyPanel extends JPanel implements KeyListener {//KeyListener 监听器 可以监听键盘事件

    //为了让小球移动,把他左下角的坐标设为变量
    int x=10;
    int y=10;
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillOval(x,y,20,20);//默认黑色
    }

    @Override
    public void keyTyped(KeyEvent e) {
        //有字符输出就会触发
    }

    @Override
    public void keyPressed(KeyEvent e) {
        //当某个键按下就会触发
        //System.out.println((char)e.getKeyCode()+"被按下");

        //根据用户按下不同键来处理小球的移动(上下左右的键)
        if(e.getKeyCode()==KeyEvent.VK_DOWN){//KeyEvent.VK_DOWN就是向下移动的箭头对应的code  在java中每一个键,会分配一个int
            y++;
        }else if(e.getKeyCode()==KeyEvent.VK_UP){
            y--;
        }else if(e.getKeyCode()==KeyEvent.VK_LEFT){
            x--;
        }else if(e.getKeyCode()==KeyEvent.VK_RIGHT){
            x++;
        }

        //让面版重绘
        this.repaint();//repaint()刷新组件外观  程序会自动调用paint()方法来绘制组件
    }

    @Override
    public void keyReleased(KeyEvent e) {
        //当某个键松下就会触发
    }
}
*/


/*
 进程是指运行中的程序
 比如我们使用QQ,就启动了一个进程,系统就会为该进程分配空间  进程是程序的一次执行程序,或是正在运行中的程序
 线程是由进程创建的一个实例化对象,一个进程有多个线程,就好比一个QQ打开多个聊天页面
 单线程:同一时刻,只允许有一个线程  多线程:同一时刻,可以有多个线程
 并发:同一时刻,多个任务交替执行 单核cpu实现多任务就是并发  人开车打电话
 并行:同一时刻 ,多个任务同时执行,多核cpu可以实现并行
 */
/*public class Demo3 {
    public static void main(String[] args) {
        Runtime runtime=Runtime.getRuntime();
        //获取当前电脑cpu数量
        int cpu=runtime.availableProcessors();
        System.out.println("当前cpu个数"+cpu);
    }
}*/

//创建线程的两种方式  1.继承Thread类,重写run方法  2.实现Runnable接口 重写run方法
/*public class Demo3 {
    public static void main(String[] args)throws InterruptedException {
        Dog dog=new Dog();
        dog.start();//启动线程  ;
        // start()本质是调用start0() ,该线程不一定立马被执行,只是将线程变成了可运行状态,具体什么时候执行,取决于CPU
        // start0是本地方法 ,JVM调用,底层是c或c++
        //真正实现多线程效果是start0,而不是重写的run
        //当main线程启动一个子线程 Thread-0 主线程不会阻塞,会继续执行
        for(int i=0;i<100;i++){
            System.out.println("主线程i="+i);

            Thread.sleep(100);//让主线程休眠
        }
    }
}
class Dog extends Thread{
    int count=0;
    @Override
    public void run() {//重写run方法 写上自己的业务逻辑
        while(true){
        super.run();
        System.out.println("汪汪汪,我是招财"+(++count)+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);//让该线程休眠一秒
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        if(count==100){
            break;//当count到10 退出while 这是线程也就退出~
        }
    }
    }
}*/

//java是单继承的,在某些情况下一个类可能继承了某个父类 这时用Thread类方法来创建线程显然不可能
//但我们可以实现Runnable接口来创建线程
/*public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        Dog dog=new Dog();
        //dog.start(); 这里不能调用start
        Thread thread=new Thread(dog);
        //创建了Thread对象,把dog对象(实现Runnable),放入Thread  这里底层使用了代理模式(设计模式)
        thread.start();

        //如果通过main线程去控制dog线程的终止 必须修改loop --->通知方式
        Thread.sleep(1000);//让主线程休眠5s,再通知dog线程退出
        dog.setLoop(false);
    }
}
class Dog implements Runnable{
    private int count=0;

    //设置一个控制变量
    private boolean loop=true;
    //线程终止 1.当线程完成任务会自动退出  2.还可以通过变量来控制run方法 即通知方式

    public void setLoop(boolean loop) {
        this.loop = loop;
    }

    @Override
    public void run() {
        while(loop){


            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }
            *//*if(count==10){
                break;
            }*//*
            System.out.println("汪汪汪,我是招财又进宝"+(++count));
        }
    }
}*/

/*public class Demo3 {
    public static void main(String[] args) {
        Dog dog=new Dog();
        MoFang mofang=new MoFang(dog);
        mofang.start();
    }
}
class Animal{

}
class Dog extends Animal implements Runnable{

    @Override
    public void run() {
        System.out.println("汪汪汪,招财有进宝");
    }
}
class MoFang implements Runnable{

        private Runnable target=null;

    @Override
    public void run() {
        if(target!=null){
            target.run();
        }
    }

    public MoFang(Runnable target) {
        this.target = target;
    }
    public void start(){
        start0();
    }
    public void start0(){
        run();
    }
}*/
//通过继承Thread 和实现Runnable接口来创建线程本质没有区别 实现Runnable接口更加适合多个线程共享一个资源的情况,并且避免了单继承的限制

    /*public class Demo3 {

    public static void main(String[] args) throws InterruptedException {
        Test test=new Test();
          //用户线程也叫工作线程,当线程的任务执行完或通知方式结束
//守护线程 一般为工作线程服务的,当用户线程执行完,守护线程自动结束
//如果我们希望当main线程结束后,子线程自动结束 只需要将子线程设为守护线程即可
//  Test test = new Test();
//   test.setDaemon(true);
//  test.start();

     线程的常用方法  1. 线程的礼让,让出cpu,但里让时间不确定,所以不一定礼让成功   Thread.yield();
       2.线程的插队,插队线程一旦成功,则肯定先执行完插入线程的所有任务 test.join();

        //测试相关方法
        test.setName("招财");//设置线程名字
        test.setPriority(Thread.MIN_PRIORITY);//更改线程优先级   1最小的  主线程休眠后执行
        test.start();
        //start底层会创建新的线程,调用run(run就是一个普通方法调用,不会启动新的线程)

        //主线程打印5个hello 然后中断 子线程的休眠
        for(int i=0;i<5;i++){
            Thread.sleep(1000);
            System.out.println("hello"+i);
        }
        //getPriority() 获取线程优先级
        System.out.println(test.getName()+"线程优先级"+test.getPriority());//getName返回该线程名字
        test.interrupt();//中断线程 ,但并没有真正的结束线程 所以一般用于中断正在休眠的线程
    }
}


class Test extends Thread{
    @Override
    public void run() {
        while(true){

            for(int i=0;i<100;i++){
                System.out.println(Thread.currentThread().getName()+"吃饭饭"+i);
            }
            try {
                Thread.sleep(20000);//休息20s
            } catch (InterruptedException e) {
                //当线程执行到一个interrupt方法时,就会catch一个异常,可以加入自己的代码
                System.out.println(Thread.currentThread().getName()+"被打断了");
            }
        }
    }
}*/

/*线程同步 Synchronized  局限性:导致程序执行效率低

同步代码块  synchronized(对象){//需要被同步的代码}
synchronized 放在方法声明中-同步方法  public synchronized void test(){//需要被同步的代码}

 同步方法(非静态)的锁可以是this,也可以是其他对象(要求同一个对象)
 同步方法(静态)的锁为当前类本身  public synchronized static void test()锁是加在 XXX.class

 互斥锁:任何时候只有一个线程访问该对象

 多个线程占用对方锁资源,但不肯想让,导致死锁   我:先玩会手机再写作业 父母:先写完作业在玩手机

 释放锁:执行结束;遇到break或return;因为异常结束;同步代码块,同步方法中执行了线程对象wait()方法,线程暂停,释放锁

 不会释放锁的情况 : 1.程序调用了Thread.sleep 和Thread.yield  2.调用了该线程的suspend()方法将线程挂起(尽量避免使用suspend()和resume()已过时)

 */

  /*  public class Demo3 {
    public static void main(String[] args) {
        Money money1=new Money();
        Thread thread1=new Thread(money1);
        thread1.setName("thread1");
        Thread thread2=new Thread(money1);
        thread2.setName("thread2");
        thread1.start();
        thread2.start();

    }
}
class Money implements Runnable{
    private int money=10000;

    @Override
    public void run() {
        while(true){
            //判断余额是否足够
            synchronized(this) {
                if (money < 1000) {
                    System.out.println("余额不足");
                    break;
                }
                money -= 1000;
                System.out.println(Thread.currentThread().getName() + "取出1000当前余额还有" + money);
            }
            try {
                Thread.sleep(1000);//休眠一秒 不然太快看不出效果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}*/

/*
文件就是保留数据的地方 word txt excel都是文件
文件在程序中以流的方式来操作  java程序--(输出流)--->文件----(输入流)---->java程序
 */
/*public class Demo3 {
    public static void main(String[] args) {

    }*/

    //1.根据路径创建File对象
    /*@Test
    public void File1(){
        String route="d:\\new1.txt";
        File file=new File(route);

        //文件相应的方法
        System.out.println("文件名字="+file.getName());
        System.out.println("文件绝对路径="+file.getAbsolutePath());
        System.out.println("文件父级目录"+file.getParent());
        System.out.println("文件大小(字节)"+file.length());
        System.out.println("文件是否存在"+file.exists());//F
        System.out.println("是不是一个文件"+file.isFile());//F
        System.out.println("是不是一个目录"+file.isDirectory());// F目录=文件夹

        try {
            file.createNewFile();
            System.out.println("文件创建成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }*/

    //2. 根据父目录文件+子路径构建
    /*@Test
    public void File2(){
        File father=new File("d:\\");
        String name="new2.txt";
        File file=new File(father,name);
        //这里的file在Java中只是一个对象
        try {
            file.createNewFile();
            //只有createNewFile 才是真正的在磁盘创建文件
            System.out.println("创建成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }*/

    //3. 根据父目录+子路径创建
   /* @Test
    public void File3(){
        //String route="d:\\";
        String route1="d:/";//也可以这样写
        String name="new3.txt";
       //File file=new File(route,name);
        File file=new File(route1,name);

        try {
            file.createNewFile();
            System.out.println("创建成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }*/

    /*@Test
    //mkdir创建一级目录  mkdirs创建多级目录
    public void test(){
        String route = "D:\\demo\\a\\b";
        File file=new File(route);
        if(file.exists()){
            System.out.println(route+"该文件存在");
        }else{
            if(file.mkdirs()){
                System.out.println(route+"创建成功");
            }else{
                System.out.println(route+"创建失败");
            }
        }
        //file.delete();//delete删除文件
    }*/
//}

/*
 IO流 Input(磁盘光盘数据到程序(内存)中)/Output(将内存的数据输出到磁盘光盘)的缩写  用于读写文件,网络通讯等
 java程序中,对于数据的输入/输出操作通过流(stream)的方式进行

 按操作数据单位不同分为   字节流(常用于二进制文件)  字符流(文本文件)
 字节流 输入流 InputStream   输出流OutputStream   字符流  输入流 Reader 输出流 Writer  这四个都是抽象类
 有这四个类派生出的子类名称都以父类名作为子类后缀名

 InputStream(字节输入流)抽象类是所有类字节输入流的超类 FileInputStream文件输入流  BufferedInputStream缓冲字节输入流 ObjectInputStream对象字节输入流

 */
//public class Demo3 {

    /*@Test
    public void readFile1(){
        String route="d:\\hello.txt";
        int readNum=0;
        FileInputStream fileInputStream = null;

        byte[] array=new byte[8];//字节数组 一次读取8个字节
        try {
            fileInputStream=new FileInputStream(route);//创建FileInputStream对象用于读取文件
            //readNum=fileInputStream.read();//从该输入流读取一个字节,如果没有输入可用,此方法阻止 返回-1则读取完毕
            //System.out.println((char)readNum);

            //while((readNum=fileInputStream.read())!=-1){
              //  System.out.print((char)readNum);
            //}
            while((readNum=fileInputStream.read(array))!=-1){
                System.out.print(new String(array,0,readNum));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //关闭文件 释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }*/

    /*@Test
    public void writeFile1(){
        String route="d:\\test.txt";
        FileOutputStream fileOutputStream=null;
        try {
            //fileOutputStream=new FileOutputStream(route);
            fileOutputStream=new FileOutputStream(route,true);//追加
            //写入一个字节
            //fileOutputStream.write('A');

            //写入字符串
            String str="hello,world";
            //getBytes()可以把字符串转换为字节数组
            //fileOutputStream.write(str.getBytes());

            fileOutputStream.write(str.getBytes(),0,5);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }*/

    //文件拷贝
   /* @Test
    public void FileCopy(){
        String route1="d:\\qq.png";
        String route2="d:\\qq1.png";
        FileInputStream fileInputStream=null;//创建文件输入流 将文件读入到程序
        FileOutputStream fileOutputStream=null;//创建文件输出流 将文件写入到指定文件
        try {
            fileInputStream =new FileInputStream(route1);
            fileOutputStream=new FileOutputStream(route2);
            //定义一个数组 提高读取效率
            byte[] array=new byte[1024];
            int readNum=0;
            while((readNum=fileInputStream.read(array))!=-1){
                //一边读 一边写
                fileOutputStream.write(array);
            }
            System.out.println("拷贝ok");
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //关闭输入流和输出流 释放资源
            try {
                if(fileInputStream!=null){
                    fileInputStream.close();
                }
                if(fileOutputStream!=null){
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }*/

    /*
    FileReader和FileWriter是字符流

    FileReader:  new FileReader(File/String)    read每次读取单个字符,返回该字符,如果到文件末尾返回-1
       read(char[])批量读取多个字符,返回读取的字符数,文件末尾返回-1
       new String(char[])将char[]转换成String
       new String(char[],off,len) 将char[]指定部分转换成String

    FileWriter:  new FileWriter(File/String) 覆盖模式,相当于流的指针在首段   new FileWriter(File/String,true)  追加模式,相当于指针在尾端
    write(int) 写个单个字符  write(char[]) 写入指定数组    write(char[],off,len)写入数组指定部分  write(string)写入字符串
    write(string,off,len)写入字符串的指定部分  toCharArray:将字符串转换成char[]
    FileWrite使用后,必须要关闭close或刷新flush,否则写入不到指定文件  fileWrite.close等价于fileWrite.flush()+关闭

    数据源就是存放数据的地方
    节点流可以从一个特定的数据源读写文件 FileReader FileWriter   底层流/低级流 直接与数据源相连
    处理流(也叫包装流)是在节点流或处理流智商,为程序提供更大的读写功能 BufferedReader(有属性Reader)  BufferedWriter(有属性Writer)
     处理流不会直接和数据源相连 使用了修饰器设计模式  优点:性能的提高(主要通过缓冲的方式提高输入输出的效率) 操作便捷
     处理流 BufferedReader  BufferedWriter 按照字符来读取数据  关闭时,只需关闭外层流即可  不要去操作二进制文件(声音 视频 docx等)
     */
    /*@Test
    public void ChuLiLiu1() throws IOException {
    String route="d:\\a.txt";
    BufferedReader bufferedReader=new BufferedReader(new FileReader(route));
    String Line;//按行读取 效率高
        while((Line=bufferedReader.readLine())!=null){//bufferedReader.readLine()按行读取文件  当返回null 表示文件读取完毕
            System.out.println(Line);
        }
        bufferedReader.close();//关闭流
    }*/
    /*@Test
    public void ChuLiLiu2() throws IOException {
        String route="d:\\b.txt";
        BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter(route));
        bufferedWriter.write("hello,java1");
        bufferedWriter.newLine();//差一个和系统相关的换行
        bufferedWriter.write("hello,java2");
        bufferedWriter.newLine();
        bufferedWriter.write("hello,java3");
        bufferedWriter.newLine();
        bufferedWriter.close();
    }*/

    /*@Test
    public void ChuLiLiuCopy() throws IOException {
        String start="d:\\a.txt";
        String end="d:\\b.txt";
        BufferedReader read=new BufferedReader(new FileReader(start));
        BufferedWriter write=new BufferedWriter(new FileWriter(end));
        String line;
        while((line= read.readLine())!=null){
            write.write(line);//每读一行就写入
            write.newLine();
        }
        //关闭流
        if(read!=null){
            read.close();
        }
        if(write!=null){
            write.close();
        }
    }*/

    /* BufferedInputStream BufferedOutputStream字节流
    对象流 ObjectInputStream(提供反序列化功能)  ObjectOutputStream(提供序列化功能)  序列化就是保存数据时,保存数据的值和数据类型  反序列化就是恢复数据的值和数据类型
       一个类是可序列化必须实现两个接口之一   Serializable//这是一个标记接口,没有方法   Externalizable该接口有方法需要实现,因此我们一般实现上面的
     序列化具有可继承性 某类实现类序列化 其子类也已经默认实现了序列化
     序列化对象,默认将所有的成员都序列化 但static 或 transient修饰时的成员不会

     */
    /*@Test
    public void ObjectOutStream_() throws IOException, ClassNotFoundException {
        String route="d:\\test.txt";//序列化后 保存文件格式不是存文本 而是按它的格式来保存
        ObjectOutputStream objectOutStream=new ObjectOutputStream(new FileOutputStream(route));

        //序列化数据
        objectOutStream.writeInt(100);//  int-->Integer(实现了Serializable)
        objectOutStream.writeBoolean(true);
        objectOutStream.writeChar('a');
        objectOutStream.writeUTF("哈哈");
        objectOutStream.writeObject(new Dog("旺财"));
        objectOutStream.close();
        System.out.println("数据保存完毕");

        ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream(route));//反序列化文件
        //读取(反序列化)的顺序要和你保存的数据(序列化)顺序一致
        System.out.println(objectInputStream.readInt());
        System.out.println(objectInputStream.readBoolean());
        System.out.println(objectInputStream.readChar());
        System.out.println(objectInputStream.readUTF());

        //如果我们需要调用Dog方法,需要向下转型
        Object dog=objectInputStream.readObject();
        System.out.println("运行类型="+dog.getClass());//底层 Object->Dog
        System.out.println(dog);
        Dog dog1=(Dog) dog;
        System.out.println(dog1.getName());
        objectInputStream.close();
    }*/


   // public static void main(String[] args) throws IOException {
        /*
    标准输入输出流             类型                 默认设备        编译类型               运行类型
    System.in标准输入         InputStream           键盘          InputStream         BufferedInputStream
    System.out标准输出       PrintStream            显示器         PrintStream        PrintStream
     */

        //System.out.println(System.in.getClass());
        //System.out.println(System.out.getClass());

        /*转换流  InputStreamReader(可以传入一个InputStream对象,并且可以指定处理编码)   OutputStreamWriter
        当处理纯文本数据时 使用字符流效率更高 并且可以解决中文问题 所以建议将字节流转为字符流
         */
        /*String route="d:\\test.txt";
        InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream(route),"gbk");
        //InputStreamReader:Reader的子类 可以将InputStream(字节流)包装成Reader(字符流)
        BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
        String str=bufferedReader.readLine();
        System.out.println("读取的内容"+str);
        bufferedReader.close();

        String route1="d:\\test1.txt";
        String format="gbk";
        OutputStreamWriter outputStreamWriter=new OutputStreamWriter(new FileOutputStream(route1),format);
        //OutputStreamWriter: Writer的子类,可以将OutputStream(字节流)包装成Writer(字符流)
        outputStreamWriter.write("hello,world");
        System.out.println("保存成功");
        outputStreamWriter.close();*/

        //打印流 PrintStream 和 PrintWriter  打印流只有输出流,没有输入流
        /*PrintStream out=System.out;
        out.print("hahahha");//在默认情况下 PrintStream输出数据的位置是 标准输出 即显示器
        //因为print底层调用的write 我们也可以直接调用write进行打印输出
        out.write("nihao".getBytes());
        out.close();
        //我们可以去修改打印流的输出位置
        System.setOut(new PrintStream("d:\\test.txt"));
        System.out.println("hello,world");

        //PrintWriter printWriter=new PrintWriter(System.out);
        PrintWriter printWriter=new PrintWriter(new FileWriter("d:\\test1.txt"));
        printWriter.print("hi,hahha");
        printWriter.close();*/

        /*Properties(父类是Hashtable) 专门用于读写配置文件的集合类 (键--值)
        .load()  加载配置文件的键值到properties对象
        getProperty(key) 根据键获取值
        setProperty(key,value) 设置键值到properties对象  有key修改没key创建
        store 将properties中的键值存储到配置文件,在idea中 如果还有中文,会存储为unicode码
        list 将数据显示指定位置
         */

/*    }
}*/
/*
class Dog implements Serializable{
    private String name;
    private static final long serialVersionUID=1L;//serialVersionUID 序列化的版本编号,可以提高兼容性
    public String getName() {
        return name;
    }

    public Dog(String name) {
        this.name = name;
    }

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













  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小手冰凉ya

你的鼓励是我最大动力谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值