学习java之路之第五周

目录

常用类

Object

hashCode()

获取对象的hash码值--->支持散列表(支持key-value键值对)
哈希码值(理解为"地址值",并非实际地址值),每一个对象的hash码值不同
keyValue
1张三
2李四
3王五
class Student请往下面翻
public class ObjectDemo {
    public static void main(String[] args) {

        //创建两个学生
        Student s1 = new Student() ;
        Student s2  = new Student() ;
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println("ammmaaa1".hashCode()) ;
        System.out.println("a1".hashCode());

        System.out.println("中国".hashCode());
        System.out.println("----------------------------------------------");
        //String toString():返回对象的字符串表示形式,结果应该是一个更容易让人读懂的信息表达式(建议所有的子类都覆盖这个方法)
        //创建一个学生
        Student student = new Student("高圆圆",44,"女") ;
        System.out.println(student) ;//com.qf.object_01.Student@14ae5a5:地址值针对开发中没有用
        //直接输出对象名称和使用对象名.toString() 是等价
        System.out.println(student.toString());
        /**
         *
         * Object的toString 的原码
         *   public String toString() {
         *         return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
         *     }
         */
        //Class c = student.getClass() ;//获取这个类的字节码文件对象  class com.qf.object_01.Student
        //Class---->public String getName(): 获取字节码对象中的全限定名称 (包名.类名)
        //System.out.println(c) ;
        //System.out.println(c.getName()+"@"+Integer.toHexString(student.hashCode()));
        //Integer---->public static String toHexString(int类型)--->int类型数据--->十六进制的字符串 表现形式
        //System.out.println(Integer.toHexString(642672));
    }

}

String toString()

返回对象的字符串表示形式,结果应该是一个更容易让人读懂的信息表达式(建议所有的子类都覆盖这个方法)
几乎Java所有类都会重写toString()方法

boolean equals(Object obj)

比较两个数据(引用类型) 是否相等

==和equals()方法区别?
==:比较两个基本类型,数据值是否相等
==:连接是两个引用类型,比较的是地址值是否相等
而Object的equals方法,默认比较的是两个引用类型的地址值是否相等,建议子类需要重写这个equals(),重写之后比较的是两个对象的成员信息是否相同!(Java中所有类都会重写!),重写equals方法,必须同时重写hashCode()方法

重写equals:比较每一个对象的成员信息是否相同 如果一样,还要比较每一个成员信息 hashCode()哈希码值是否一样,如果都相同系统认为这个两个人是一样的!
idea快捷键:alt+ins—>equals and hashcode方法

class Student请往下面翻
public class ObjectDemo2 {
    public static void main(String[] args) {
            //两个基本类型 : == 比较两个数据值是否相等!

        //创建两个学生对象
        Student s1 = new Student("高圆圆",25,"女") ;
        Student s2 = new Student("高圆圆",25,"女") ;
        System.out.println(s1==s2) ;//false
        System.out.println(s1.equals(s2)); //false  (没有重写比较地址值是否相等)
                                           //true :重写Object的equals方法比较是内容是否相同

        /**
         * Object的equals方法源码
         *  public boolean equals(Object obj) {    s1.equals(s2)
         *         return (this == obj);            return s1 ==s2; //默认比较地址值
         *     }
         */

    }
}

clone():克隆

protected Object clone() throws CloneNotSupportedException 创建对象并返回它的"副本"
方法里面本身就会带有CloneNotSupportedException:克隆不支持的异常(当要对某个Object的类进行克隆如果这个类不能实现cloneable接口,那么就会出现这个异常)

public class ObjectDemo3 {

    public static void main(String[] args) throws CloneNotSupportedException {

        //没有使用clone之前:
        //创建一个学生对象
        Student s1 = new Student("高圆圆",44,"女") ;
        System.out.println(s1);
        //定义一个Student类型的变量s3
        //将s1赋值给s3
        Student s3 = s1 ;
        System.out.println(s3) ;

        System.out.println("----------------------------------------") ;
        //Object提供了一个clone方法 来完成复制一个副本
        Student s4 = new Student("文章",35,"男") ;
        System.out.println(s4);
        Object obj = s4.clone();//调用者必须处理本身带有异常的方法
        System.out.println(obj) ;
    }
}

class Student在这里啦

//class Student
public class Student implements Cloneable{


    private String name ;//姓名
    private int age ;     //年龄
    private String gender ; //性别

    public Student() {
    }

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

    //手动书写toString
   /* public String toString(){
        return "学生的姓名是:"+name+",年龄是:"+age+",性别是:"+gender ;
    }*/

    //idea生成的toString——————>alt+ins--->toString

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


    //重写了hashCode和equals方法
    @Override
    //比较两个对象的成员信息是否都相同
    public boolean equals(Object o) {      //s1 .equals(s2)         Object o = new Student("高圆圆"25,"女") ;多态
        if (this == o) return true;  //s1==s2 :直接返回true
        if (o == null || getClass() != o.getClass()) return false;
                                /*
                                *   if(o==null || this.getClass() !=o.getclass())
                                * */

        Student student = (Student) o; // 向下转型

        if (age != student.age) return false;  //if(s1.age !=student.age)  //年龄不相同
        if (name != null ? !name.equals(student.name) : student.name != null) return false;
                    //if(s1.name !=null ? !s1.name.equal(student.name))
        return gender != null ? gender.equals(student.gender) : student.gender == null;
                            //return s1.gender !=null   s1.gender.equals(student.gender)
                            //上面的if都成不成立:age,name都相同
                            //gender.equals(student.gender) :gender--->String类型已经重写了Object的equals方法
                            //比较是字符串内容是否 相同 s1.gender "女"   student.gender --->s2.gender "女"

    }

    @Override
    //每一个成员信息哈希码值是否一样
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;  //s1.name.hashCode()  "高圆圆".hashCode()
        result = 31 * result + age;  // 31 *"高圆圆".hashCode()+ 25
        result = 31 * result + (gender != null ? gender.hashCode() : 0);  // 31 *"高圆圆".hashCode()+"女".hashCode()
        return result;
    }

    //重写clone方法--->使用它父类(非Java语言实现的)

    @Override
    protected Object clone() throws CloneNotSupportedException {
        System.out.println("进行复制副本");
        return super.clone();
    }
}

Scanner

构造方法:
public Scanner(InputStream source) 创建键盘录入对象
创建一个文本扫描器
Scanner 对象名 = new Scanner(System.in) ;
—>System类—变量名
public static final InputStream in

成员方法:
nextXXX():获取功能
public int nextInt() :录入int类型
public String nextLine() ;录入String类型

判断功能:
public boolean hasNextInt():判断录入的下一个数据是否为int类型,是,返回true,否则false
public boolean hasNextLine():判断录入的下一个数据为一行内容
键盘录入的时候,先录入int,在录入String ----nextLine() ,这块会出现被漏掉(“回车符号”)

解决方案:
1.在第一个录入int之后,重新创建一个新的键盘录入对象Scanner ,然后在使用nextLine()
2.在录入String---- String next()

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

        //需要输入流(io流后面讲)
        InputStream input = System.in ;

        //public Scanner(InputStream source)
        //创建文本扫描器对象
        Scanner sc = new Scanner(input) ;   //形式参数需要输入流--->System.in
        System.out.println("请输入一个数据:");

        //boolean hasNextXXX():判断录入的下一个是否为XXX类型
        if(sc.hasNextInt()){
            //录入下一个为int类型
            int number = sc.nextInt() ;//InputMismatchException:输入类型和结果不匹配!
             System.out.println("number:"+number);
        }else if(sc.hasNextLine()){
            String line = sc.nextLine() ;
            System.out.println("line:"+line);
        }else{
            System.out.println("目前不提供这个类型的方法...");
        }
    }
}

String类

String类: 这个类final修饰不能被继承
字符串是不变; 它们的值在创建后不能被更改(字符串是一个常量,存储在常量池中)

String类的特点?

String是一个常量,不可变的字符序列,一旦被赋值,其值不可更改!
推荐的创建方式:

String s  = "abc" ;
		//String s = new String("abc") ;
		
	    String str1 = new String("Hello");
		String str2 = new String("Hello");
		System.out.println(str1.equals(str2));
		System.out.println(str1 == str2);
		
		String s3 = "hello" ;
		String s4 = "world" ;
		String s5 = "helloworld" ;
		System.out.println(s5==(s3+s4)) ;
		System.out.println(s5.equals(s3+s4)) ;
		System.out.println(s3.equals(s4)) ;
		System.out.println(s3==s4) ;	
		
		System.out.println(s5 == ("hello"+"world"));

构造方法:
public String():空字符串 类似于 String s = “” ;
public String(String original):构造一个字符串对象,里面指定一个字符串常量值
public String(byte[] bytes) :使用平台默认字符集(idea默认utf-8)解析解码—>字节数组—>字符串
String(byte[] bytes, int offset, int length) :将一部分字节数组构造成字符串
public String(char[] value):将字符数组—构造成String
public String(char[] value,int offseet,int len):将一部分字符串数组构造成字符串

public class StringDemo {
    public static void main(String[] args) {
        //测试
        //创建一个字符串 public String()
        String s1 = new String() ;
        System.out.println("s1:"+s1) ;//不是地址值,String类重写了Object的toString方法
        System.out.println(s1.length());
        System.out.println();
        System.out.println("--------------------------------------------------") ;
        // public String(String original):构造一个字符串对象,里面指定一个字符串常量值
        String s2= new String("helloworld") ;
        System.out.println("s2:"+s2) ;
        System.out.println(s2.length());
        System.out.println("----------------------------------------------------");
        // public String(byte[] bytes) :使用平台默认字符集(idea默认utf-8)解析解码--->字节数组--->字符串
        byte[] bytes = {97,98,99,100,101} ;
        String s3 = new String(bytes) ;
        System.out.println("s3:"+s3) ; //abcde 将字节数组中每一个数字,转成ASCII码表对应的字符
        System.out.println(s3.length());
//        String(byte[] bytes, int offset, int length) :将一部分字节数组构造成字符串

        String s4 = new String(bytes,0,2) ;
        System.out.println("s4:"+s4) ;
        System.out.println(s4.length());

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

        /* public String(char[] value):将字符数组---构造成String
         public String(char[] value,int offseet,int len):将一部分字符串数组构造成字符串*/
        char[] chs = {'她','喜','欢','我'} ;
        String s5 = new String(chs) ;
        System.out.println("s5:"+s5) ;
        System.out.println(s5.length());
        String s6 = new String(chs,1,3) ;
        System.out.println("s6:"+s6) ;
        System.out.println(s6.length());

        //实际开发中,创建字符串不会用上这些格式
       // String s7 = new String("JavaEE") ;
        String s8 = "JavaEE" ;//开发中推荐的格式
    }
}

String类相关的获取功能

  1. public char charAt(int index) :获取指定索引处的字符
  2. int length():获取字符串的长度
  3. public String concat(String str)拼接功能-- 将一个字符串拼接到指定字符串的后面(末尾追加)
  4. public String substring(int beginIndex):截取—>从指定位置开始截取,默认截取到末尾结束!
    public String substring(int beginIndex, int endIndex)截取—>从指定位置开始截取到指定位置结束,包前不包后(包含第一个位置,不包含最后一个位置,只能取到endIndex-1处)
  5. public String[] split(String regex):拆分(分割) ,按照指定的分割符将字符串拆分成字符串数组
  6. public int indexOf(int ch) :返回此字符第一次在字符串中出现的索引值
    public int lastIndexOf(int ch):返回此字符最后一次在字符串中出现的索引值
public class StringDemo3 {
    public static void main(String[] args) {

        //已知字符串
        String s = "Java";
        System.out.println(s.indexOf('a'));
        System.out.println(s.lastIndexOf('a'));


        //public char charAt(int index) :获取指定索引处的字符
        /*System.out.println(s.charAt(0));
        System.out.println(s.charAt(1));
        System.out.println(s.charAt(2));
        System.out.println(s.charAt(3));
        System.out.println(s.charAt(4));
        System.out.println(s.charAt(5));*/
        //遍历字符串的每一个字符
        for(int x = 0 ; x < s.length();x++){
            char ch = s.charAt(x) ;//获取到获取每一个字符
            System.out.print(ch+"\t");
        }
        System.out.println();
        System.out.println("-----------------------------------------------");

        //public String concat(String str)拼接功能-- 将一个字符串拼接到指定字符串的后面(末尾追加)
        String s2 = "helloworld" ;
        String s3 = "高圆圆" ;
        String s4 = s2.concat(s3) ;
        System.out.println(s4);

        //需求:已知一个数组,定义一个方法,将数组的元素拼接成String
        int[] arr = {68,29,14,76,5} ;
        String resultStr = arrayToString(arr) ;
        System.out.println("resultStr:"+resultStr);
        System.out.println("-----------------------------------------------");
        //concat的用法 + substring()+转换功能--- 需求:给定一个字符串,输入"Hellowold" ,输出 "hELLOWORLD"
        //4)public String substring(int beginIndex):截取--->从指定位置开始截取,默认截取到末尾结束!
        //      public String substring(int beginIndex, int endIndex) 截取--->从指定位置开始截取到指定位置结束
        //包前不包后(包含第一个位置,不包含最后一个位置,只能取到endIndex-1处)
        String s5 = "hellowodl" ;
        System.out.println(s5.substring(5));
        System.out.println(s5.substring(5,8));
        System.out.println("----------------------------------------------------");
        String str = "JavaEE-Python-Golang-R-C-Php" ;
        //public String[] split(String regex):拆分(分割) ,按照指定的分割符将字符串拆分成字符串数组
        String[] strs = str.split("-");
        //遍历字符串数组
        for(int x = 0 ; x < strs.length;x++){
            System.out.print(strs[x]+"\t");
        }


    }
    //定义静态方法,返回值String
    public static String arrayToString(int[] arr){
        //创建一个空串
       // String s = ""  ;
       // s += "[" ;
      //  String s2 = s.concat("[");
        StringBuffer sb = new StringBuffer() ;
        sb.append("[") ;
        //遍历数组
        for(int x = 0 ; x < arr.length ;x++){
            //判断最后一个角标
            if(x==arr.length-1){
                //拼接最后一个元素
                //s += arr[x] ;
                //s += "]" ;
                sb.append(arr[x]+"]") ;

            }else{
                //中间元素
               // s += arr[x] ;
               // s += ", " ;
                sb.append(arr[x] +", ") ;


            }
        }
        return sb.toString() ;
    }
}

String类的转换功能

  1. char[] toCharArray() 将字符串转换成字符数组
  2. byte[] getBytes() 平台默认字符集编码(String—>byte[]) 和
    byte[] getBytes(String charset):指定的字符集进行编码
    String(byte[] bytes) :(bytes[]—>String ) 平台默认字符集解码
    String(byte[] bytes,String charset) :(bytes[]—>String ) 指定字符集解码
  3. public String toLowerCase():将字符串转换成小写
    public String toUpperCase():将字符串转换成大写
  4. 万能方法: 可以将任何数据类型---->String
    public static String valueOf(int i/float…Object)
    编码和解码必须一致,否则乱码!
public class StringDemo4 {
    public static void main(String[] args) throws UnsupportedEncodingException {

        String s = "helloworld" ;
        //char[] toCharArray() 将字符串转换成字符数组
        char[] chs = s.toCharArray();//{'h','e','l','l','o','w','o','r','l','d'}
        //Arrays:数组工具类---toString(任意类型数组)--转换成String
        String resultStr = Arrays.toString(chs);
        System.out.println(resultStr) ;
        System.out.println("------------------------------------------------");
        //byte[] getBytes() 平台默认字符集编码(String--->byte[])   和
        // byte[] getBytes(String charset):指定的字符集进行编码
        String s2 = "我爱中国" ;
        byte[] bytes = s2.getBytes(); //平台字符集 utf-8 (一个中文对应三个字节)
        //System.out.println(bytes);地址值
        System.out.println(Arrays.toString(bytes));

        //解码 bytes[]--->String
        // String(byte[] bytes) :(bytes[]--->String  ) 平台默认字符集解码
        // *      String(byte[] bytes,String charset) :(bytes[]--->String  ) 指定字符集解码
       // String s3 = new String(bytes,"gbk") ;//gbk:一个中文对应两个字节
       // String s3 = new String(bytes,"utf-8") ;//gbk:一个中文对应两个字节
        String s3 = new String(bytes) ;
        System.out.println(s3) ;
        System.out.println("-----------------------------------------------");
        //public String toLowerCase():将字符串转换成小写
        //public String toUpperCase():将字符串转换成大写
        System.out.println(s.toUpperCase());
        String s4 = "JAVAEE" ;
        System.out.println(s4.toLowerCase());
        System.out.println("---------------------------------------------") ;

        //已知int--->String
        int i = 100 ;
        //public static String valueOf(int i/float....Object)
        String s5 = "" ;
        System.out.println(s5+=i) ;
        String s6 = String.valueOf(i);//"100"
        System.out.println(s6); //"100"
    }
}

String的判断/替换/去除两端空格 (了解)相关功能

判断功能:

  • boolean contains(String str):判断大串中是否包含指定子字符串
  • boolean endsWith(String suffix):判断是否以指定结尾的字符串
  • public boolean startsWith(String prefix):判断是否指定的字符串开头
  • boolean equals(Object anObject)。:比较两个字符串内容是否相同
  • boolean equalsIgnoreCase(String anotherString) :不区分大小写比较两个字符串是否相同
  • public boolean isEmpty():判断字符串是否空 ,长度为0,true
    空串,和空对象? 一样吗?
    不一样
  • public String replace(char oldChar,char newChar) :替换功能
  • public String trim() :去除字符串两端空格 (一般io流中: 文件读写文件)
public class StringDemo {
    public static void main(String[] args) {
        //String s1 = "" ;  //空字符串
       // String s2 = null ; //空对象 (没有值)
        //  boolean contains(String str):判断大串中是否包含指定子字符串
        String s = "helloworldjavaee";
        System.out.println(s.contains("owo"));
        System.out.println(s.contains("ak47"));
        System.out.println("--------------------------------------------") ;
        /**
         * boolean endsWith(String suffix):判断是否以指定结尾的字符串
         * public boolean startsWith(String prefix):判断是否指定的字符串开头
         */
        System.out.println(s.endsWith("ee"));
        System.out.println(s.startsWith("he"));
        System.out.println(s.startsWith("高圆圆"));
        System.out.println("--------------------------------------------") ;
        /**
         *  boolean equals(Object anObject)。:比较两个字符串内容是否相同
         *  boolean equalsIgnoreCase(String anotherString) :不区分大小写比较两个字符串是否相同
         */
        String s2 = "helloWorldJavaEE" ;
        System.out.println(s.equals(s2));
        System.out.println(s.equalsIgnoreCase(s2));
        System.out.println("--------------------------------------------") ;
        // public boolean isEmpty():判断字符串是否空 ,长度为0,true
        s2 = "" ;
        System.out.println(s2.isEmpty());
//        public String replace(char oldChar,char newChar)  :替换功能
//        public String trim() :去除字符串两端空格 (一般io流中:  文件读写文件)
        System.out.println(s.replace("l","*")) ;
        System.out.println("---------------------------------------------") ;
        // public String trim() :去除字符串两端空格 (一般io流中:  文件读写文件)
        String str = " hello           " ;
        System.out.println(str+"----");
        String str2 = str.trim();
        System.out.println(str2+"----");
    }
}



已知int[] arr = {87,69,24,13,54} ;
将数组拼接成字符串!(使用方法来完成!)

+字符串拼接符号 ----->“”+10
concat(String str) 这两种哪一个高效? +拼接符号更高效一些
String s = null ;
s.concat(“hello”) ; 左边不能为空对象,如果这样导致NullPointerException:空指针

public class StringTest2 {
    public static void main(String[] args) {
        int[] arr = {87,69,24,13,54} ;
        String result1 = arrayToString(arr) ;
        System.out.println(result1);
        System.out.println("---------------------------") ;
        String result2 = arrayToString2(arr);
        System.out.println(result2);
    }

   //方式2
    public static String arrayToString2(int[] arr){
        //定义一个字符串
        String s = "" ;
        s = s.concat("[") ;
        for(int x = 0 ; x < arr.length;x++){
            if(x==arr.length-1){
                s = s.concat(arr[x]+"]") ;
            }else{
                s = s.concat(arr[x]+", ") ;
            }
        }
        return s ;
    }
    //方式1:
    public static String arrayToString(int[] arr){
        //创建一个空串

        StringBuffer sb = new StringBuffer() ;
        sb.append("[") ;
        //遍历数组
        for(int x = 0 ; x < arr.length ;x++){
            //判断最后一个角标
            if(x==arr.length-1){
                sb.append(arr[x]+"]") ;
            }else{
                sb.append(arr[x]+", ") ;
            }
        }
        return sb.toString() ;
    }
}


需求:给定一个字符串,输入"Hellowold" ,输出 “hELLOWORLD”

1)可以录入字符串 s1
2)将字符串的一个字符截取出来 s2
substring(0,1) -->“H”----->转换小写 toLowerCase()
3)s1字符串 subString(1) ----> “ellowold”—>转换成大写 toUpperCase() —>s3
4) 2)和3)结果----->concat拼接功能----->结果s4
5) 输出
键盘录入字符串:包含大写字母字符,数字字符,小写字母字符,统计每个字符出现的个数?(不包含特殊字符串)
键盘录入字符串:将字符串反转 了
输入"abc" — >“cba”

public class StringTest {
    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;

        //提示并录入
        System.out.println("请输入一个字符串:") ;
        String s1  = sc.nextLine() ;

        //1)截取
        String s2 = s1.substring(0, 1);
        //2)转换成小写
        String s3 = s2.toLowerCase();
        //3)从1位置开启截取到末尾
        String s4 = s1.substring(1);
        //4)将s4---转换成大写
        String s5 = s4.toUpperCase();
        //5)将s和s5拼接
        String result = s3.concat(s5) ;
        System.out.println(result);
    }
}

StringBuffer类(字符串缓冲区,线程安全的类)/StringBuilder

StringBuffer:线程安全的类,支持可变字符序列!
线程–>依赖于进程,线程执行的最小单元! (这周多线程讲)

线程安全----->意味着 “同步”---->执行效率低
举例: 银行类的网站/医院平台
线程不安全----> “不同步”---->执行效率高
举例:
论坛网站

构造方法:

  • public StringBuffer() —>空参构造,初始容量16个字符
  • public StringBuffer(int capacity)—>指定容量大小的字符串字符串缓冲区(很少用)
  • public StringBuffer(String str)—>将指定的字符串内容构造到字符串缓冲区中,容量=当前str的长度+16
  • int length()获取字符串缓冲区长度
  • int capacity() :获取容量大小
public class StringBufferDemo {
    public static void main(String[] args) {

        // public StringBuffer()  --->空参构造,初始容量16个字符
        StringBuffer sb = new StringBuffer() ;
        System.out.println("sb:"+sb) ;
        System.out.println(sb.length()) ;
        System.out.println(sb.capacity());

        System.out.println("---------------------------------------") ;
        //public StringBuffer(int capacity)--->指定容量大小的字符串字符串缓冲区
        StringBuffer sb2 = new StringBuffer(20) ;
        System.out.println("sb2:"+sb2) ;
        System.out.println(sb2.length()) ;
        System.out.println(sb2.capacity());

        System.out.println("---------------------------------------") ;
        // public StringBuffer(String str)--->将指定的字符串内容构造到字符串缓冲区中,容量=当前str的长度+16
        StringBuffer sb3 = new StringBuffer("高圆圆") ;//--->创建一个字符缓冲区char[]--->将里面的字符串--->append(str)
        System.out.println("sb3:"+sb3) ;
        System.out.println(sb3.length());
        System.out.println(sb3.capacity());
    }
}

StringBuffer的追加和插入

  • public StringBuffer append(任意Java类型):将指定的类型追加字符串缓冲区的序列中,返回自己本身
  • public StringBuffer insert(int index,String str/可以任意Java类型) 在指定位置处插入指定的数据,返回字符串缓冲区本身

StringBuufer的获取功能

  • public char charAt(int index):获取字符串缓冲区中指定位置的字符,返回指定的字符

StringBuffer的删除

  • StringBuffer delete(int start, int end) :删除从指定位置开始到指定位置结束(end-1)的字符,返回字符串缓冲区本身
  • StringBuffer deleteCharAt(int index):删除指定位置处的字符,返回值字符串缓冲区本身

StringBuffer的替换功能:

  • public StringBuffer replace(int start,int end,String str)将字符串缓冲区中的从指定位置开始到指定位置结束(end-1)的字符序列使用指定的字符串进行替换

StringBuffer的截取功能:

  • public String substring(int beginIndex)
  • public String substring(int beginIndex,int endIndex)
public class StringBufferDemo2 {
    public static void main(String[] args) {
        //创建一个字符串缓冲区
        StringBuffer sb  = new StringBuffer() ;
        System.out.println("sb:"+sb);
        // public StringBuffer append(任意Java类型):将指定的类型追加字符串缓冲区的序列中
        //StringBuffer sb1 = sb.append(100);
       // StringBuffer sb2 = sb1.append("hellworld");
       // StringBuffer sb3 = sb2.append('a');
       // System.out.println(sb3);
        sb.append(100).append("helloworld").append('A').append(true).append(new Object()) ;
        System.out.println("sb:"+sb);
        System.out.println("----------------------------------------") ;
        StringBuffer sb2 = new StringBuffer() ;
        sb2.append("hello") ;
        sb2.append("world") ;
        sb2.append("javaee") ;
        System.out.println("sb2:"+sb2) ;
        // public char charAt(int index):获取字符串缓冲区中指定位置的字符
        System.out.println(sb2.charAt(4));
        System.out.println("------------------------------------------") ;
        //StringBuffer delete(int start, int end)  :删除从指定位置开始到指定位置结束(end-1)的字符,返回字符串缓冲区本身
        //StringBuffer deleteCharAt(int index):删除指定位置处的字符,返回值字符串缓冲区本身
        System.out.println(sb2.delete(5,8));
        System.out.println(sb2.deleteCharAt(5));
        System.out.println("---------------------------------------------") ;
        //public StringBuffer insert(int index,String str/可以任意Java类型) 在指定位置处前面插入指定的数据
        System.out.println(sb2.insert(5,"高圆圆"));
        System.out.println("----------------------------------------------") ;
        //public StringBuffer replace(int start,int end,String str)
        System.out.println(sb2.replace(8,13,"你好"));
    }
}

StringBuffer的特有功能:

public StringBuffer reverse()将字符串缓冲区中的字符序列进行反转

键盘录入一个字符串,判断字符串是否为对称字符串? true/false
“abmba”

分析:
1)键盘录入一个字符串
2)将字符串---->char[] toCharArray 字符数组
3)将字符数组 chs[0] — chs[数组长度-1]
chs[1] ---- chs[数组长度-2]

保证数组长度/2

public class StringBufferDemo3 {
    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;

        //提示并录入数据
        System.out.println("请您输一个字符串数据:" );
        String line = sc.nextLine() ;

        //调用功能
        boolean flag = compareString(line);
        System.out.println(flag);
        System.out.println("------------------------------------------------") ;
        boolean flag2 = compareString(line);
        System.out.println(flag);

        System.out.println("------------------------------------------------");
        //StringBuffer的reverse反转
        StringBuffer sb = new StringBuffer() ;
        System.out.println("sb:"+sb) ;
        sb.append("hello");
        sb.append("world") ;
        System.out.println("sb:"+sb);
        sb.reverse() ;
        System.out.println("sb:"+sb);
        System.out.println("------------------------------------------------");
        boolean flag3 = compareString3(line);
        System.out.println(flag3);

    }
    //方式3:利用StringBuffer的反转功能,结合StringBuffer和String类型转换
    public static boolean compareString3(String s){
        //分步走
        //1)创建一个字符串缓冲区
        /*StringBuffer sb = new StringBuffer() ;
        //2)将s追加到缓冲区中
        sb.append(s) ;
        //3)将字符串字符缓冲区中的字符序列反转
        StringBuffer sb2 = sb.reverse();
        //4)将sb2缓冲区---转换成String
        String str = sb2.toString();
        //5)使用反转之的最终的字符串结果和s进行比较 equals
        return str.equals(s) ;*/

        //一步走
        return new StringBuffer(s).reverse().toString().equals(s) ;

    }

    //方式2: 将字符串--->字符数组
    //遍历每一个字符,for里面两个索引,起始start和最终索引start
    public static boolean compareString2(String s){
        char[] chs = s.toCharArray();
        for(int start =0,end = chs.length-1; start<end;start++,end--){
            //chs[start]   chs[end]
            if(chs[start]!=chs[end]){
                return false ;
            }
        }
        return true ;
    }

    //方式1
    public static boolean compareString(String s){
        //1)将s---->转换成字符数组
        char[] chs = s.toCharArray();
        /**
         * 将字符数组 chs[0]  ---  chs[数组长度-1]
         *                   chs[1] ---- chs[数组长度-2]
         *                   ...
         *                  保证  数组长度/2
         */
        for(int x = 0 ; x < chs.length/2;x++){
            //判断
            //chs[0]    chs[chs.lengh-1-0]
            //chs[1]    chs[chs.lengh-1-1]
            if(chs[x] != chs[chs.length-1-x]){
                return false ;
            }
        }
        return true ;
    }
}

String和StringBuffer的相互转换

String—>StringBuffer
方式1:
StringBuffer的有参构造
String s = “hello” ;
StringBuffer sb = new StringBuffer(s) ;
方式2:
StringBuffer的无参构造+append(String str)
StringBuffer sb2 = new StringBuffer() ;
sb2.append(s) ;

StringBuffer—>String
方式1:
StringBuffer的成员方法 public String toString()
StringBuffer buffer = new StringBuffer(“abc”) ;
String s = buffer.toString() ;
方式2:
String的构造方法 String(StringBuffer sb)
StringBuffer buffer2 = new StringBuffer(“abc”) ;
String s2 = new String(buffer2) ;



在实际开发中,牵扯很多类型之间的相互转换
将A类型–>B类型,因为想去使用B类型的功能
但是又可能将B类型—>A类型,最终需求的结果是A类型
String---->StringBuffer
StringBuffer---->String

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

        //String---->StringBuffer
        String s = "hello" ;
       /* String s = "hello" ;
        StringBuffer sb = s ;*/ //两个类型不匹配
        //方式1 :使用StringBuffer(String str)有参构造
        StringBuffer sb = new StringBuffer(s) ;
        System.out.println("sb:"+sb) ;

        System.out.println("-----------------------------------") ;
        //方式2:使用StringBuffer()空参构造,结合append(String str)追加
        StringBuffer sb2 = new StringBuffer() ;
        sb2.append(s) ;
        System.out.println("sb2:"+sb2);


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

        //StringBuffer---->String
        StringBuffer buffer = new StringBuffer("helloJavaEE") ;
        //方式1:StringBuffer--->public String toString()
        String str = buffer.toString();
        System.out.println(str) ;
        System.out.println("----------------------------------------------------") ;
        //方式2:String类----->构造方法public String(StringBuffer buffer)
        String str2 = new String(buffer) ;
        System.out.println(str2);
    }
}

Integer类

包装的int类型的值

四类八种基本类型---------->包装类类型(引用类型) :jdk5以后的自动拆装箱

byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean
基本类型引用类型String
StringIntegerint

需求:
控制台打印int类型的取值范围
int—>Integer---->静态的常量
public static final int MAX_VALUE
public static final int MIN_VALUE
求出100的二进制/八进制/十六进制(使用程序)
public static String toBinaryString(int i):将十进制–转换二进制的字符串形式
public static String toHexString(int i)将十进制–转换十六进制的字符串形式
public static String toOctalString(int i)将十进制–转换八进制的字符串形式

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

        //  public static final int MAX_VALUE
        // public static final int MIN_VALUE
        System.out.println(Integer.MIN_VALUE) ;
        System.out.println(Integer.MAX_VALUE) ;
        System.out.println("------------------------------------------") ;
     /*   public static String toBinaryString(int i):将十进制--转换二进制的字符串形式
        public static String toHexString(int i)将十进制--转换十六进制的字符串形式
        public static String toOctalString(int i)将十进制--转换八进制的字符串形式*/
        System.out.println(Integer.toBinaryString(100));
        System.out.println(Integer.toOctalString(100));
        System.out.println(Integer.toHexString(100));
    }
}

Integer的构造方法:
public Integer(int value) :将int类型数据包装为Integer类型
public Integer(String s)throws NumberFormatException :将字符串类型包装Integer类型,如果字符串非数字字符串,
就会出现NumberFormatExceptio数字格式化异常

jdk5以后的新特性:自动拆装箱 /静态导入(导入到方法的级别,前提方法必须为静态)/增强for循环/可变参数…
基本类型会自动装箱为 引用类型: int–>Integer
引用类型会拆箱为 基本类型 : Integer–>int

public class IntegerDemo2 {
    public static void main(String[] args) {
        //创建一个Integer类对象
        //public Integer(int value) :将int类型数据包装为Integer类型
        Integer i = new Integer(100) ;  //将int----Integer类型
        i += 200 ;                            //将Integer--->int--->在和200相加---->int--->Integer
        System.out.println(i) ;
        /*
        * 利用反编译工具类:将上面的字节码文件---反编译
        * 	Integer i = new Integer(100);//100 装箱 Integer
        *                                               //public int intValue():Integer--->int 拆箱
		    i = Integer.valueOf(i.intValue() + 200);  // --->(i.intValue()+200)--->300赋值给i
		    *                                       //将一个整数赋值给Integer--->底层执行的Integer.valueOf(300)
		    System.out.println(i);               //输出结果
        * */
        System.out.println("------------------------------------------------") ;
        //public Integer(String s)throws NumberFormatException :
        //String s = "hello" ; //字符串必须为数字字符串
        String s = "10" ;
        Integer ii = new Integer(s) ;
        System.out.println(ii);
        //Integer i = 100 ;
       // Integer i = new Integer(100) ;
    }
}

将int类型数据赋值给Integer类型变量,它的内部缓存区IntegerCache完成了什么事情?

/*
Integer i = 整数值;
执行Integer类的valueOf(整数值)
IntegerCahce: 静态成员内部类
if(整数值>= IntegerCahce.low && 整数值<=IntegerCache.high){
//如果在-128-127之间,从Integer类型数组中取数据 Integer[]
return IntegerCache.cache[整数- (-Integer.low)]
}
//如果不再范围内,直接开堆内存空间 创建实例!
return new Integer(整数值)
*/
Integer i1 = 127 ;
Integer i2 = 127 ;
System.out.println(i1==i2) ; //true
Integer i3 = 128 ;
Integer i4 = 128 ;
System.out.println(i3==i4) ; //false

类型转换

int---->String 静态方法public static String toString(int i)
String—>int (使用居多) public static int parseInt(String s)
前后端交互:前端提交的数据几乎String类型

public class IntegerDemo3 {
    public static void main(String[] args) {
        //int--->String
        int i = 100 ;
        String result = "" ;
        //方式1:字符串拼接符号+
        result += i;
        System.out.println(result) ;
        System.out.println("---------------------------------");
        //方式2:int--->Integer---->String
        //Integer(int i) ---->publict String toString()
        Integer ig = new Integer(i) ;
        String result2 = ig.toString();
        System.out.println(result2); //"100"
        System.out.println("---------------------------------");
        //方式3:Integer的静态方法public static String toString(int i)
        String result3 = Integer.toString(i);
        System.out.println(result3);

        System.out.println("--------------------------------------") ;
       // String---->int
        String s = "20" ; //数字字符串
       //方式1:String--->Integer --->public int intValue()
        Integer ig2 = new Integer(s) ;
        int value = ig2.intValue();
        System.out.println(value); //20
        System.out.println("-----------------------------------------") ;
        //方式2:直接转换public static int parseInt(String s) throws NumberFormatException
        int value2 = Integer.parseInt(s);
        System.out.println(value2); //20
        //parseXXX方法在任意的基本类型对应的类型都存在(万能方法)
        //String--Long-->long---->Long.parseLong(字符串)
        //String--Float-->float--->Float.parseFloat(小数字符串)
    }
}

看程序,写结果
Integer 对象名 = 整数值; ---->执行底层的Integer.valueOf(整数值)---->
IntegerCache静态的成员内部类(内部缓存区)---->low (-128)/high(127)
如果整数值在-128-127之间,直接从IntegerCachec里面的cache[]里面取值
如果超出范围内, new Integer(整数值); 重新创建Integer类对象,堆内存开辟空间
public static Integer valueOf(int i) { //整数值
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

Integer 对象名 =  整数值;
Integer 对象名  =  new Integer(整数值) ;   
	这两个不一样
public class IntegerTest {
    public static void main(String[] args) {
        Integer i1 = 127 ;
        Integer i2 = 127 ;
        System.out.println(i1==i2) ;//true
        System.out.println(i1.equals(i2)) ;//true
        
        Integer i3 = 127 ;// 在-128-127之间:IntegerCache内部缓存区取数据
        Integer i4 = new Integer(127) ; //堆内存开辟空间
        System.out.println(i3==i4) ; //false
        System.out.println(i3.equals(i4)) ;//true
        
        Integer i5 = 128 ;          //valueOf(128)--- return new Integer(128) ;
        Integer i6 = 128 ;          //return new Integer(128) ;
        System.out.println(i5==i6) ;//在-128-127之间:   128超了范围
                                    //false
        System.out.println(i5.equals(i6)) ; //true

        Integer i7 =  new Integer(128) ;
        Integer i8 =  new Integer(128) ;
        System.out.println(i7==i8) ;
        System.out.println(i7.equals(i8)) ;
    }
}

Character类

构造方法

Character(char value):包装一个char字符类型 char---->Character

成员方法

public static boolean isDigit(char ch):判断是否为数字字符
public static boolean isUpperCase(char ch):判断是否为大写字母字符
public static boolean isLowerCase(char ch):判断是否为小写字母字符

public class CharacterDemo {
    public static void main(String[] args) {
        //创建一个Character对象
        Character character = new Character((char) 97) ;
        System.out.println(character);
        Character character2 = new Character('a') ;
        System.out.println(character2);
   
        System.out.println(Character.isDigit('0'));
        System.out.println(Character.isDigit('A'));
        System.out.println(Character.isDigit('a'));
        System.out.println(Character.isUpperCase('0'));
        System.out.println(Character.isUpperCase('A'));
        System.out.println(Character.isUpperCase('a'));

    }
}



判断字符串的个数

需求:键盘录入一个字符串,统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
分析:
 1)定义统计变量三个,分别代表大写字母字符,小写字母字符,数字字符
2)创建键盘录入对象,录入String  (包含大小写字母以及数字字符)
3)将字符串---->字符数组
4)遍历字符数组
获取到每一个字符
 判断 这个字符  'A' 'Z'  --->大写字母字符
			    'a'  'z'  --->小写字母字符
			    '0'  '9'  ---> 数字字符
键盘录入任意的小写字母字符,最终输出 结果
录入"bcassabcd"
结果: "a(2)b(2)c(2)d(1)ss(2)"
public class Test {
    public static void main(String[] args) {
        //1)定义统计变量三个,分别代表大写字母字符,小写字母字符,数字字符
        int smallCount = 0 ;
        int bigCount = 0 ;
        int numberCount = 0;

        //2)创建键盘录入对象,录入String  (包含大小写字母以及数字字符)
        Scanner sc = new Scanner(System.in) ;
        //提示并录入字符串
        System.out.println("请输入一个字符串(包含大小写字母以及数字字符):") ;
        String line = sc.nextLine() ;

        //将字符串---->字符数组
        char[] chs = line.toCharArray();
        //遍历字符数组
        for(int x = 0 ; x <chs.length ;x++){
            //接收每一个字符
            char ch = chs[x] ;
            /**
             * 判断 这个字符  'A' 'Z'  --->大写字母字符
             *              'a'  'z'  --->小写字母字符
             *              '0'  '9'  ---> 数字字符
             */

           //使用Character的判断功能
            if(Character.isDigit(ch)){
                //判断是否为数字
                numberCount++;
            }else if(Character.isUpperCase(ch)){
                //是否大写字母字符
                bigCount++;
            }else if(Character.isLowerCase(ch)){
                //是否为小写字母字符
                smallCount++ ;
            }else {
                System.out.println("非法字符");
            }
          /*  if(ch>='A' && ch<='Z'){
                bigCount ++;
            }else if(ch>='a' && ch<='z'){
                smallCount ++ ;
            }else{
                numberCount++;
            }*/
        }
        System.out.println("大写字母字符共有"+bigCount+"个");
        System.out.println("小写字母字符共有"+smallCount+"个");
        System.out.println("数字字符共有"+numberCount+"个");
    }
}

Date类

java.util.Date:特定的日期

构造方法:

public Date():系统时间的日期格式

成员方法:

public long getTime():获取指定Date对象的系统时间毫秒值
public class DateDemo {
    public static void main(String[] args) {

        //创建一个Date对象
        Date date  = new Date()  ;
        System.out.println(date) ;//       Date日期格式
        //public long getTime():获取指定Date对象的系统时间毫秒值
        long time = date.getTime();
        System.out.println(time);
    }
}

String日期文本

Date日期格式 ----->String日期文本 —>格式化操作
2022/11/15 2022年11月15日 ----------->Date (重点 ) ---->解析
应用场景:用户注册 填写 出生日期 “1995-05-27” String---->数据库Date格式
格式化或者解析:使用DateFormat类,它是一个抽象类,不能实例化,用的抽象类的子类SimpleDateFormat

Date日期—>String格式化

public final String format(Date date)
1)创建当前日期对象
Date date2 = new Date() ;
2)创建解析器对象
SimpleDateFormat sdf2 = new SimpleDateFormat(“yyyy-MM-dd”) ;
//3)格式化
String dateStr =sdf2.format(sdf2) ;

构造方法

SimpleDateFormat(String pattern) pattern模式 : y:代表年 yyyy 代表整个年份 :2022
M:代表月份 MM 11 07 06
d:月份中的日 dd 03 11 01
H:0-23(一天的小数数) HH
m:小时的分钟数 mm

String日期文本---->Date 解析

public Date parse(String source) throws ParseException :
如果String日期文本 和转换器SimpleDateFormat(String pattern) 里面的模式不匹配就会造成解析异常!

String s = “2008-5-12”
1)创建解析器
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ") ;//解析出问题了!
2)Date date = sdf.parse(s) ;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateDemo2 {
    public static void main(String[] args) throws ParseException {
        //将Date---->String 格式化
        //创建一个Date对象,当前系统日期对象
        Date date = new Date() ;
        //SimpleDateFormat(String pattern)   :转换器
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
        //public final String format(Date date)
        String dateStr = sdf.format(date);
        System.out.println(dateStr);
        System.out.println("---------------------------------------------------") ;
        //给定一个日期文本 String---->Date (重点)
        String str = "2020-12-31" ;
        //中间桥梁
//        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日") ;//模式不匹配
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd") ;
        //public Date parse(String source)  throws ParseException :
        Date date2 = sdf2.parse(str);
        System.out.println(date2);

    }
}

键盘录入出生年月日 ,比如"1995-05-20" ,计算来到这个世界有多少天了?

分析:
1)键盘录入一个出生年月日—>String
2)String日期文本---->解析java.util.Date日期对象
3)获取你出生年月日的那个Date日期对象的时间毫秒值 long getTime() oldTime
4)获取当前系统时间毫秒值 newTime
public static long currentTimeMillis() System类的静态方法
5) long time = newTime-oldTime
6) time/1000/60/60/24

public class DateTest {
    public static void main(String[] args) throws ParseException {
        // 1)键盘录入一个出生年月日--->String
        Scanner sc = new Scanner(System.in) ;
        //提示并录入数据
        System.out.println("请输入一个数据: ") ;
        String birthday = sc.nextLine() ;

        //String日期文本---->解析java.util.Date日期对象
        Date date = DateUtils.string2Date(birthday, "yyyy-MM-dd") ;
        //获取你出生年月日的那个Date日期对象的时间毫秒值 long getTime()    oldTime
        long oldTime = date.getTime() ;

        //获取当前系统时间毫秒值    newTime
        //public static long currentTimeMillis() System类的静态方法
        long newTime = System.currentTimeMillis();

        //时间差值
        long time = newTime - oldTime ;
        System.out.println("您来到这个世界有"+(time/1000/60/60/24)+"天");
    }
}

自定义一个工具类:—构造私有化,外界不能new
定义一个两个静态方法
调用jdk提供的一个类的方法----如果这个方法本身throws 异常类名,我们必须处理!

处理方式
1)throws :抛出 (自己玩)
2) 捕获异常 (开发中)
try{
可能出现问题的代码
}catch(异常类名 对象名){
对象名.printStackTrice();跟踪堆栈
}

public class DateUtils {
    private DateUtils(){}

    /**
     * 将Date日期格式转换成String文本格式
     * @param date  转换的日期对象
     * @param pattern 指定的模式
     * @return 返回字符串文本格式
     */
    public static String date2String(Date date,String pattern){

        return new SimpleDateFormat(pattern).format(date) ;
    }

    /**
     * 将String日期文本解析为Date日期对象
     * @param source  指定的字符串日期文本
     * @param pattern  指定的模式
     * @return  返回的日期对象
     */
    public static Date string2Date(String source,String pattern) throws ParseException {

        return  new SimpleDateFormat(pattern).parse(source) ;
    }
}

System类: 不能实例化

三个成员变量 —静态常量

static PrintStream err“标准”错误输出流。
static InputStream in“标准”输入流。 (InputStream:字节输入流 --读数据)
static PrintStream out “标准”输出流。(PrintStream字节打印流—>
OutputStream字节输出流—写/打印)

成员方法

public static long currentTimeMillis():获取系统时间毫秒值(应用场景:计算程序的执行效率)
public static void exit(int status):参数为0,正常终止jvm
public static void gc():手动开启垃圾回收器
开启垃圾回收器,会调用Object类的finalize()垃圾回收方法
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) :复制数组
参数1:原数组
参数2:原数组中的某个位置
参数3:目标数组
参数4:目标数组中的某个位置
参数5:从原数组的那个位置srcPos指定长度复制到目标数组中

public class SystemDemo {
    public static void main(String[] args) {
        //System.err.println("错误信息");
        PrintStream ps =  System.out ;  //返回字节打印流:是字节输出流的一种(io流中)
        //PrintStream---->public void print(任意java类型的数据)/public void println(任意java类型 数据)
        ps.println("helloworld");

        //System.out.println("helloworld");
        System.out.println("----------------------------------------------") ;
        //public static long currentTimeMillis():获取系统时间毫秒值(应用场景:计算程序的执行效率)
        long start =System.currentTimeMillis() ;
        for(int x = 0 ; x < 10000; x ++){
            System.out.println(x+"hello") ;
        }
       // public static void exit(int status):参数为0,正常终止jvm
        //System.exit(0);
        long end =System.currentTimeMillis() ;
        System.out.println("共耗时:"+(end-start)+"毫秒");

        System.out.println("---------------------------------------------") ;
        //public static void gc():手动开启垃圾回收器
        //开启垃圾回收器,会调用Object类的finalize()垃圾回收方法
        Person p = new Person("高圆圆",44) ;
        System.out.println(p) ;
      //  p = null ;// 不指定内存空间了, 现在手动开启垃圾回收器
       // System.gc();
        System.out.println("---------------------------------------------------") ;
        /**
         * public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)  :复制数组
         *                参数1:原数组
         *                参数2:原数组中的某个位置
         *                参数3:目标数组
         *                参数4:目标数组中的某个位置
         *                参数5:从原数组的那个位置srcPos指定长度复制到目标数组中
         */
        int[] arr = {1,2,3,4,5} ;
        int[] arr2 = {6,7,8,9,10} ;
        //使用Arrays数组工具类toString(数组)--->String
        System.out.println("复制之前:") ;
        System.out.println(Arrays.toString(arr));
        System.out.println(Arrays.toString(arr2));
        System.out.println("-----------------------------------") ;
        System.out.println("复制之后:") ;
        System.arraycopy(arr,1,arr2,1,3);
        System.out.println(Arrays.toString(arr));
        System.out.println(Arrays.toString(arr2));
    }
}

Random:伪随机数生成器

public Random() 构造方法:创建新的随机数生成器
public Random(long seed) 构造方法:创建新的随机数生成器(以指定的long 的类型计算随机数):每一次均分布局一样的 (不推荐)
成员方法
public int nextInt():获取的int类型的取值范围
public int nextInt(int n):[0,n)随机数

生成一个随机数

public class RandomDemo {
    public static void main(String[] args) {
        //使用Random类产生随机数
        Random random = new Random() ;
        //10个随机数
        for(int x = 0 ; x < 10 ; x++){
           // int n = random.nextInt();
            int n = random.nextInt(100);
            System.out.println(n);
        }
    }
}


使用数组存储5个学生,学生有姓名和年龄,(对象数组),将数组学生信息遍历出来–
1)需要有学生类Student -name/age
2)创建一个学生数组(存储学生的数组)
数据类型[] 对象名 = new 数据类型[数组长度] ;
3)创建5个学生
students[角标值] =s1第一个学生
4)遍历这个对象数组
Student s = students[x] ---->每一个学生
s.getXXX() :获取学生信息

 class Student
public class Student {
    private String name ;//姓名
    private int age ; //年龄

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

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

        //对象数组:能够对象的数组---引用类型
        //数据类型[] 对象名 = new 数据类型[数组长度] ;
        Student[] students = new Student[5] ;
        //创建5个学生
        Student s1 = new Student("文章",35) ;
        Student s2 = new Student("姚笛",30) ;
        Student s3 = new Student("王宝强",38) ;
        Student s4 = new Student("马蓉",32) ;
        Student s5 = new Student("李云迪",40) ;

        //给数组元素赋值
        students[0] = s1 ;
        students[1] = s2;
        students[2] = s3;
        students[3] = s4;
        students[4] = s5;

        //遍历对象数组
        for(int x = 0 ; x < students.length ; x++){
            //student[x] 就是每一个学生
            //System.out.println(students[x]);//直接对象名--->本身调用toString()

            Student s = students[x] ;
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}

java.util.Calendar :日历类

是一个抽象类,不能new
这个类里面的某些功能(静态功能)—一定完了这个类的子类的实例!

创建日历实例—>public static Calendar getInstance()

Calendar提供静态的字段(成员变量—>静态常量)
public static final int DATE:月中的日期值
public static final int MONTH:年中的月份值 (0-11),获取之后+1
public static final int YEAR:年份值

Calendar提供成员方法:

public int get(int field):获取日历的字段值
参数就是需要通过Calendar访问的静态常量的那些字段

public abstract void add(int field,int amount) 给日历字段设置偏移量,添加或者减去 amount值

public final void set(int year,int month,int date) 设置日历字段

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

        //创建日历类对象
        //public static Calendar getInstance()
        Calendar c = Calendar.getInstance();
        System.out.println(c) ;
        System.out.println("-----------------------------------");

        //获取当前系统日历的年,月,日...
        /**
         *  Calendar提供静态的字段(成员变量--->静态常量)
         *           public static final int DATE:月中的日期值
         *          public static final int MONTH:年中的月份值
         *            public static final int YEAR:年份值
         *
         *   Calendar提供成员方法:
         *           public int get(int field):获取日历的字段值
         *                        参数就是需要通过Calendar访问的静态常量的那些字段
         */
        //获取年份
        int year = c.get(Calendar.YEAR) ;
        //获取月份
        int month = c.get(Calendar.MONTH)+1 ;
        //获取月中的日期
        int day = c.get(Calendar.DATE) ; //DAY_OF_MONTH和DATE通用
        System.out.println(year+"-"+month+"-"+day);
        System.out.println("-------------------------------------------") ;

        //public abstract void add(int field,int amount)    给日历字段设置偏移量,添加或者减去 amount值
        //5年前的今天
        c.add(Calendar.YEAR,-5) ; //给年份设置偏移日期

        //5年前的10天前
        //给月中日期设置偏移量
        c.add(Calendar.DATE,-10) ;
        //获取年份
        int year2  = c.get(Calendar.YEAR) ;
        int month2 = c.get(Calendar.MONTH)+1 ;
        //获取月中的日期
        int day2 = c.get(Calendar.DATE) ; //DAY_OF_MONTH和DATE通用
        System.out.println(year2+"年"+month2+"月"+day2+"日") ;
        System.out.println("----------------------------------------");

        //public final void set(int year,int month,int date) 设置日历字段
        c.set(2018,10,20) ;
         year2  = c.get(Calendar.YEAR) ;
        month2 = c.get(Calendar.MONTH)+1 ;
        //获取月中的日期
        day2 = c.get(Calendar.DATE) ; //DAY_OF_MONTH和DATE通用
        System.out.println(year2+"年"+month2+"月"+day2+"日") ;




    }
}


键盘录入任意年份,来计算二月有多少天?(使用Calendar日历类)

public class Test2 {
    public static void main(String[] args) {
        //1)创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;

        //提示并录入数据
        System.out.println("请输入年份:") ;
        int year = sc.nextInt() ;

        //创建日历对象
        Calendar c = Calendar.getInstance();
        //设置日历 中年月日
        c.set(year,2,1); ///----->月份的值+1  ---实际3月1日
        //给Calendar字段月份中的日期DATE--->往前推一天  (设置偏移量)
        c.add(Calendar.DATE,-1);
        //获取月份中日期:
        int day = c.get(Calendar.DATE) ;
        System.out.println("二月的有"+day+"天");
    }
}

BigDecimal:作用针对小数进行精确计算

构造方法

BigDecimal(String value):参数 “小数字符串值”
BigDecimal(int value):整数
BigDecimal(double value):浮动类型

成员方法:

public BigDecimal add(BigDecimal augend):加
public BigDecimal subtract(BigDecimal subtrahend)减
public BigDecimal multiply(BigDecimal multiplicand)乘
public BigDecimal divide(BigDecimal divisor):除
public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)
参数1:除数值
参数2:scale保留小数位数
参数3:roundingMode舍入的模式 BigDecimal提供静态常量

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

        //创建BigDecimal(String value):参数 "小数字符串值"
        BigDecimal bigDecimal = new BigDecimal("1.05") ;
        BigDecimal bigDecimal2 = new BigDecimal("0.5") ;
        /**
         * public BigDecimal add(BigDecimal augend):加
         *  public BigDecimal subtract(BigDecimal subtrahend)减
         *   public BigDecimal multiply(BigDecimal multiplicand)乘
         *  public BigDecimal divide(BigDecimal divisor):除
         */
        System.out.println(bigDecimal.add(bigDecimal2));
        System.out.println(bigDecimal.subtract(bigDecimal2));
        System.out.println(bigDecimal.multiply(bigDecimal2));
        System.out.println(bigDecimal.divide(bigDecimal2));
        /**
         * public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)
         *              参数1:除数值
         *               参数2:scale保留小数位数
         *                参数3:roundingMode舍入的模式  BigDecimal提供静态常量
         */
        System.out.println(bigDecimal.divide(bigDecimal2,2,BigDecimal.ROUND_HALF_UP)); //支持四舍五入
    }
}

jdk5 的新特性

1)静态导入---->导入到方法的级别
import static 包名.类名.方法名;
前提使用静态导入,这个类的方法必须为静态
在使用静态导入的时候,导入jdk提供的一些工具类里面静态方法的时候,我们定义的方法不能和它方法名冲突
如果冲突了,静态导入是不识别,这个时候必须导入全限定名称 :包名.类名.方法名(xxx)

2)可变参数,当一个方法形式参数不知道多少个,这个时候可以使用可变参数(类似一个数组)
public 返回值类型 方法名(数据类型… 参数名)

import  static java.lang.Math.abs;
import static java.lang.Math.max; //最大值
import static java.lang.Math.min; //最小值
import static java.lang.Math.pow;  //pow(a,b)  a的b次幂
public class JDK5StaticDemo {
    public static void main(String[] args) {

        //java.lang.Math:针对数学运算的类
        //public static double/int abs(double/int a,double/int b):求绝对值
        //...都是静态成员方法
        System.out.println(Math.abs(-10));
        System.out.println(Math.abs(100));

        System.out.println(java.lang.Math.abs(-100));//使用到了静态导入,方法名和自定义的方法名冲突了
        System.out.println(max(10,15));
        System.out.println(min(5,3));
        System.out.println(pow(2,3));
        System.out.println("---------------------------------");
        int sum = add(10, 20, 30, 40, 50);
        System.out.println(sum) ;
    }

    //自定义的abs方法
    public static void abs(int a){
        System.out.println(a);
    }

    //求多个数据和
    public  static int add(int...a){//类似一个数组
        int sum = 0 ;
        //遍历
        for(int x = 0 ; x < a.length  ;x++){
            sum += a[x] ;
        }
        return sum ;

    }
}

集合

Colleciton:没有jdk提供直接实现,通过具体的子接口List/Set的子实现类实现
创建集合的时候<E> :里面存储的引用类型的元素
模拟数组,创建集合的时候就明确了集合中存储的数据类型,否则导致程序不安全!

在这里插入图片描述

常用基本功能:

添加

boolean add(E e):添加元素 E—>Object任意Java元素

删除

删除集合中的元素boolean remove(Object o)
暴力删除(将集合全部清空)void clear()

判断

boolean isEmpty():判断集合是否为空
boolean contains(Object o):判断集合是否包含指定的元素

public class CollectionDemo {
    public static void main(String[] args) {
        //创建一个Collection,没有带泛型
       // Collection  c = new ArrayList() ;
        //创建的集合,带上<泛型>
        Collection<String> c = new ArrayList<>() ; //new 集合<默认和前面的泛型类型一致,可以不写> () ;  jdk7新特性 泛型推断
        System.out.println(c);
        // boolean add(E e):添加元素 E--->Object任意Java元素
       // boolean flag1 = c.add("hello") ;

       // boolean flag2 = c.add(100) ;
       // boolean flag3 = c.add('A') ;
        /**
         *   public boolean add(E e) {
         *        ///...中间的逻辑在数据扩容
         *         return true;
         *     }
         */
       // System.out.println(flag1+"---"+flag2+"---"+flag3);
        c.add("hello") ;
        c.add("world") ;
        c.add("javaee") ;
        //c.add(100) ;

        System.out.println("--------------------------------") ;
//        删除集合中的元素boolean remove(Object o)
//            暴力删除(将集合全部清空)void clear()
        //System.out.println(c.remove("javaee"));
//        c.clear();
        //boolean isEmpty():判断集合是否为空
        // boolean contains(Object o):判断集合是否包含指定的元素
       // System.out.println(c.isEmpty()) ;
        System.out.println(c.contains("高圆圆"));
        System.out.println(c.contains("world"));
        System.out.println(c);

    }
}

遍历

1)将集合转换对象数组
Object[] toArray() 不推荐,还是变成数组!

//jdk提供@SuppressWarnings("all")  解决警告问题 (实际开发中,项目打包--安装-->部署--->上线)
//@SuppressWarnings("all") //压制警告
public class CollectionDemo2 {
    public static void main(String[] args) {
        //创建一个集合--->存储String
        Collection<String>  c  = new ArrayList<>() ;
        //添加字符串数据
        c.add("hello") ;
        c.add("world") ;
        c.add("javaEE") ;
        c.add("Mysql") ;
        System.out.println(c);

        //转换成数组Object[] toArray()
        Object[] objects = c.toArray();
        for(int x = 0 ; x < objects.length ;x++){
            //objects[x]数组中---    相当于每一个元素 Object 对象名 = new String();//多态 向上转型
           // System.out.println(objects[x]);
            //遍历这些字符串并且同时它的长度
           // System.out.println(objects[x]+"---"+objects[x].length()); //Object类型没有length()
            //向下转型
            String s = (String) objects[x];
            System.out.println(s+"---"+s.length());


        }

    }
}

迭代器——Collection的专有遍历方式

Iterator iterator()
Iterator接口提供了功能:Object next() :获取下一个可以遍历的元素
boolean hasNext():判断如果迭代器里面有元素,则返回true,然后在获取!
在这里插入图片描述

需求:使用Collection存储String类型,并去使用迭代器将元素一一遍历,打印控制台
1)使用Collection集合存储5个学生,使用迭代器的这种方式进行遍历!
2)使用Collection集合存储String类型,如果这个字符串是"world",那么添加一个新的字符串数据"javaEE",
然后遍历集合中的数据

public class CollectionDemo {
    public static void main(String[] args)  {
        //创建一个集合对象
        Collection<String> c = new ArrayList<>() ;

        //存储String类型的元素
        c.add("hello") ;
        c.add("world") ;
        c.add("java") ;
        c.add("javaee") ;

        //Iterator<E> iterator() 获取迭代器
        Iterator<String> it = c.iterator();

        // Iterator接口提供了功能:E next() :获取下一个可以遍历的元素
        //先判断,在获取
        //boolean hasNext():判断如果迭代器里面有元素,则返回true,然后在获取!

        /*
        if(it.hasNext()){
            //第一次获取
            String next = it.next();
            System.out.println(next);
        }

        //第二次获取
        if(it.hasNext()){
            System.out.println(it.next());
        }

        //第三次获取
        if(it.hasNext()){
            System.out.println(it.next());
        }
        //第四次获取
        if(it.hasNext()){
            System.out.println(it.next());
        }
//        System.out.println(it.next());
        //java.util.NoSuchElementException 没有元素的异常
        //第五次获取
        if(it.hasNext()){
            System.out.println(it.next());
        }

         */
        //迭代器标准代码
        while(it.hasNext()){
            //有下一个元素
            //再获取
            String  s = it.next() ;
            System.out.println(s+"---"+s.length());
        }

    }
}

使用Collection集合存储String类型

如果这个字符串是"world",那么添加一个新的字符串数据"javaEE",然后遍历集合中的数据

分析:
存储"hello",“world”,“java”
使用迭代器遍历集合
获取元素—如果这个元素和"world"一致,给集合中添加"javaEE"

按照上面的分析完成代码实现出现下面错误
java.util.ConcurrentModificationException:并发修改异常
并发:某个时间点
并行:某个时间段
出现并发修改异常的原因:
当使用迭代器去遍历元素的时候,不能同时在使用集合操作元素;

解决方案:
1)使用迭代器遍历,迭代器添加,但是现在Collection的迭代器没有添加功能----->List集合的特有 列表迭代器ListIterator
2)使用集合遍历,集合添加, Collection没有直接通过角标获取元素的功能---->List集合E get(int index)
for(int x= 0 ;x < list集合对象.size();x++){
String s = list集合对象.get(x) ;
if(“world”).equals(s){
list集合对象.add(“javaee”);
}
}

public class CollectionTest2 {
    public static void main(String[] args) {
        //创建Collection
      //  Collection<String> c = new ArrayList<>() ;

        //使用List集合
        List<String> c = new ArrayList<>() ;
        ///添加数据
        c.add("hello") ;
        c.add("world") ;
        c.add("java") ;

        //获取迭代器
       // Iterator<String> it = c.iterator();
        //获取List列表迭代器
        //ListIterator<String> it = c.listIterator();  //List的迭代器遍历
        //遍历迭代器
       /* while(it.hasNext()){//迭代器的元素来自于集    合
            //获取
            String s = it.next() ;
            //加入判断
            if("world".equals(s)){//如果迭代器中的元素是world,使用集合给里面添加元素
                //给集合添加"javaEE"
                //c.add("javaEE") ;
                //列表迭代器里面就是add方法:插入元素  (在指定元素的后面插入)
                it.add("javaee");

            }
            System.out.println(s+"---"+s.length());
        }
        Iterator<String> it2 = c.iterator();
        while(it2.hasNext()){
            System.out.println(it2.next());
        }*/
        //优化代码
        //解决方案2:集合遍历,集合添加List集合的普通for
        for(int x = 0 ; x < c.size() ; x++){
            //获取元素
            String s = c.get(x);
            if("world".equals(s)){
                c.add("javaEE") ;
            }
        }

        //遍历元素
        for(String s:c){
            System.out.println(s);
        }
    }
}


应用

使用Collection存储自定义对象(学生对象--->针对学生类) 并进行遍历存储5个学生,并遍历学生信息(使用方式1---转换成数组)

class Student

public class Student {
    private String name ; //姓名
    private int age ; //年龄

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

方式一:

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

        //创建一个容器集合对象
        Collection<Student> c = new ArrayList<>() ;

        //创建5个学生对象
        Student s1 = new Student("曹操",45) ;
        Student s2 = new Student("刘备",35) ;
        Student s3 = new Student("关羽",32) ;
        Student s4 = new Student("张飞",30) ;
        Student s5 = new Student("周瑜",20) ;

        //将5个学生对象添加到集合中
        c.add(s1) ;
        c.add(s2) ;
        c.add(s3) ;
        c.add(s4) ;
        c.add(s5) ;

        //将集合转换成Object[] toArray()
        Object[] objects = c.toArray();  // 相当于Object  objs = new Student() ;多态
        for(int x=  0 ; x < objects.length ; x++){
           // System.out.println(objects[x]) ;//每一个学生对象---->toString()   //Object类型  存储的Student对象
            //使用Student的特有功能 getXXX()获取信息
            //向下转型
            Student s = (Student) objects[x];
            System.out.println(s.getName()+"---"+s.getAge());

        }
    }

方式二

public class CollectionTest1 {
    public static void main(String[] args) {
        //创建集合对象
        Collection<Student> c = new ArrayList<>() ;
        //创建5学生对象

        //创建5个学生对象
        Student s1 = new Student("曹操",45) ;
        Student s2 = new Student("刘备",35) ;
        Student s3 = new Student("关羽",32) ;
        Student s4 = new Student("张飞",30) ;
        Student s5 = new Student("周瑜",20) ;

        c.add(s1) ;
        c.add(s2) ;
        c.add(s3) ;
        c.add(s4) ;
        c.add(s5) ;

        //获取Collection的迭代器,将元素存储在迭代器中
        Iterator<Student> it = c.iterator();
        while(it.hasNext()){
            //获取下一个元素
            Student student = it.next();
            System.out.println(student.getName()+"---"+student.getAge());
        }

    }
}

List集合

List集合的特点

允许集合元素重复(实际应用,List集合如何去重?),而且有序集合(存储和取出一致)

List集合的特有功能:

void add(int index, E element):在指定位置插入新的元素
E get(int index):获取指定位置处的元素
E set(int index,E element):在指定位置处替换(修改)指定的元素
ListIterator listIterator():List集合的专有遍历–>列表迭代器

public class ListDemo {
    public static void main(String[] args) {
        //创建List集合对象--存储String
        List<String> list = new ArrayList<>() ;

        list.add("hello") ;
        list.add("world") ;
        list.add("hello") ;
        list.add("hello") ;
        list.add("javaee") ;
        list.add("javaee") ;
        System.out.println(list) ;
        // void add(int index, E element):在指定位置前面插入新的元素
        list.add(2,"高圆圆") ;
        System.out.println(list);
        System.out.println("-------------------------------------------------") ;
        // E get(int index):获取指定位置处的元素
        System.out.println(list.get(4));
        System.out.println("-----------------------------------------------------");
        // E set(int index,E element):在指定位置处替换(修改)指定的元素
        System.out.println(list.set(1,"mysql"));
        System.out.println(list);

        System.out.println("---------------------------------------------------");
        // ListIterator<E> listIterator():List集合的专有遍历-->列表迭代器
        //ListIterator--->正向列表遍历 :boolean  hasNext()  + E next():获取下一个元素
        //                  反向遍历列表 booean hasPrevious()+E pervious:获取上一个元素 (必须有正向遍历列表)

        ListIterator<String> lit = list.listIterator();
        while(lit.hasNext()){
            //获取
            String s = lit.next() ;
            System.out.println(s+"---"+s.length());
        }
        System.out.println("------------------------------------------");
    /*    while(lit.hasPrevious()){
            //获取
            String s = lit.previous() ;
            System.out.println(s+"---"+s.length());
        }*/


        //将上面List集合中所有元素遍历
        //方式1:List集合继承Collection---->Object[] toArray()
        Object[] objects = list.toArray();
        for(int x = 0 ; x < objects.length; x++){
            String s = (String) objects[x];
            System.out.println(s+"---"+s.length());
        }
        System.out.println("---------------------方式2---------------------");
        // 方式2:Collection的迭代器Iterator iterator()
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String s = it.next(); //it.next():使用一次 ,不能使用多次
            System.out.println(s+"---"+s.length());
        }
        System.out.println("---------------------方式3 /方式4---------------------");
        //列表迭代器ListIterator
        //方式4:List集合的get(int index) +size() 的普通for循环
        for(int x = 0 ; x < list.size(); x++){
            //通过角标获取元素
            String s = list.get(x);
            System.out.println(s+"---"+s.length());
        }

        System.out.println("---------------------方式5--------------------");
        /**
         * jdk5新特性 增强for循环---->目的 为了替代迭代器(集合,存储引用类型),简化代码书写程度
         * for(泛型里面存储的数据类型 变量名 : 集合或者数组名称){
         *     使用变量名
         * }
         *
         * 增强for的特点: 前台条件:集合或者数组对象不能为null,否则NullPointerException
         */
        for (String s : list) {
         /*   if("mysql".equals(s)){
                list.add("go") ; // 使用增强for遍历元素,集合添加元素,会出现并发修改异常ConcurrentModificationException
            }*/
            System.out.println(s+"---"+s.length());
        }

    }
}

List集合的遍历方式

1)Collection集合的toArray()
2)Collection集合的迭代器Iterator iterator()
3)List集合的特有迭代器ListIterator listIterator()
4)List集合的E get(int index) 和int size()结合的普通for
5)增强for循环格式

增强for的格式以及作用

增强for循环—作用:替代迭代器,简化代码书写
for(存储的数据类型 变量名: 集合对象或者数组对象 ){
使用这个变量;
}

List集合的应用

import com.qf.collection_04.Student;
import java.util.ArrayList;
/**
* 分析:
* 1)ArrayList<ArrayList<Student>> 大的集合创建出来
* 2)泛型---->ArrayList<Student>类型,子集合 ,创建3个子集合,每一个子集合都需要添加到大集合中
* 3)遍历大集合
* for(ArrayList<Student> array:大的集合对象名){
* for(Student s:array){
* //获取到数据
* }
* }
*
*/
public class ListTest {
public static void main(String[] args) {
//1)ArrayList<ArrayList<Student>> 大的集合创建出来
ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ;
//2)创建三个子集合
ArrayList<Student> array1 = new ArrayList<>() ;
Student s1 = new Student("高圆圆",20) ;
Student s2 = new Student("赵又廷",25) ;
array1.add(s1) ;
array1.add(s2) ;
//将array1添加到大集合中
bigArray.add(array1) ;
ArrayList<Student> array2 = new ArrayList<>() ;
Student s3 = new Student("文章",35) ;
Student s4 = new Student("马伊琍",44) ;
array2.add(s3) ;
array2.add(s4) ;
//将array2添加到大集合中
bigArray.add(array2) ;
ArrayList<Student> array3 = new ArrayList<>() ;
Student s5 = new Student("孙俪",30) ;
Student s6 = new Student("邓超",35) ;
array3.add(s5) ;
array3.add(s6) ;
//将array3添加到大集合中
bigArray.add(array3) ;
//ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ;
//遍历上面大集合
System.out.println("学生的信息如下:\t");
for(ArrayList<Student> array :bigArray){
//子集合的泛型:学生类型
for(Student s:array){
System.out.println("姓名是:"+s.getName()+"\t"+"年龄是:"+s.getAge());
}
}
}
}

List去重

去重思想
在这里插入图片描述

使用List集合存储重复String类型的数据,保证集合的元素唯一!(去重)

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

        //1)创建一个集合
        List<String> list = new ArrayList<>() ;

        //2)添加重复的String
        list.add("hello") ;
        list.add("world") ;
        list.add("hello") ;
        list.add("java") ;
        list.add("java") ;
        list.add("android") ;
        list.add("world") ;
        list.add("android") ;
        list.add("JavaEE") ;
        list.add("hello") ;
        list.add("android") ;

        //3)新建一个集合
        List<String> newList = new ArrayList<>() ;
        //4)遍历以前的集合
        for(String s:list){
            //一一获取以前集合中所有元素
            //使用新集合判断里面如果不包含这个元素,不重复,添加到新集合中
            if(!newList.contains(s)){
                newList.add(s) ;
            }
        }

        //5)遍历新集合
        for(String s:newList){
            System.out.println(s);
        }
    }
}
/**
 * 集合的contains方法底层源码:
 * public boolean contains(Object o) {  //Object o = new String("xx") ;//多态
 *         return indexOf(o) >= 0;
 *     }
 *
 *
 *     indexOf()----->依赖于Object的equals()方法
 *     而String类型 人家已经重写了Obejct的equals()方法
 *     比较的字符串内容是否相同
 */

学生对象

public class Student {
    private String name ; //姓名
    private int age ; //年龄

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    //alt+ins--->equals and hashCode

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name.equals(student.name);
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}

import java.util.ArrayList;
import java.util.List;

/**
 * 使用List集合存储重复Student类型的数据,保证集合的元素唯一!(学生对象唯一)
 * 学生有姓名,年龄----如果成员信息一样,应该是同一个人
 */
public class ListTest2 {
    public static void main(String[] args) {

        //创建List对象
        List<Student> list = new ArrayList<>() ;

        //创建学生对象
        Student s1 = new Student("高圆圆",32) ;
        Student s2 = new Student("高圆圆",32) ;
        Student s3 = new Student("高圆圆",32) ;
        Student s4 = new Student("文章",35) ;
        Student s5 = new Student("文章",32) ;
        Student s6 = new Student("赵又廷",36) ;
        Student s7 = new Student("赵又廷",36) ;
        Student s8 = new Student("马伊琍",38) ;

        //添加集合中
        list.add(s1) ;
        list.add(s2) ;
        list.add(s3) ;
        list.add(s4) ;
        list.add(s5) ;
        list.add(s6) ;
        list.add(s7) ;
        list.add(s8) ;

        //新建一个集合
        List<Student> newList = new ArrayList<>() ;
        //遍历以前的集合
        for(Student s:list){
            //使用新集合判断,不包含这个元素就添加
            if(!newList.contains(s)){
                newList.add(s) ;
            }
        }
        //遍历新集合
        for(Student s:newList){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}
/**
 * List存储自定义类型,
 * 而使用新建集合思想去重,contains()底层依赖于Obejct的equals
 * 而Object的equals方法默认比较 是== ,两个对象地址值是否一样
 * 存储自定义类型保证元素唯一,自定义类型重写equals方法()/hashCode(),成员信息是否一样,如果一样,还要比较成员的哈希码值是否一样
 * 都相同,就是同一个人
 */
import java.util.ArrayList;
import java.util.List;

/**
 * 使用List集合存储重复String类型的数据,保证集合的元素唯一!(去重),不使用新建集合思想!
 * 利用选择排序的思想
 *      使用0角标对应的元素依次和后面元素比较,如果后面元素和前面的元素重复,将后面的元素干掉,(集合中remove(元素))
 *     重新遍历集合!
 */
public class ListTest3 {
    public static void main(String[] args) {
        //1)创建一个集合
        List<String> list = new ArrayList<>() ;

        //2)添加重复的String
        list.add("hello") ;
        list.add("world") ;
        list.add("hello") ;
        list.add("java") ;
        list.add("java") ;
        list.add("android") ;
        list.add("world") ;
        list.add("android") ;
        list.add("JavaEE") ;
        list.add("hello") ;
        list.add("android") ;

        //选择排序
        for(int x = 0 ; x < list.size()-1 ;x++){
            for(int y = x+1; y<list.size() ; y++){
                //逻辑
                //使用0角标对应的元素依次和后面元素比较,如果后面元素和前面的元素重复,将后面的元素干掉,(集合中remove(元素))
                if(list.get(x).equals(list.get(y))){
                    //将后面的元素干掉
                    list.remove(y) ;
                    y-- ;
                }
            }
        }
        //遍历
        for(String s:list){
            System.out.println(s);
        }
    }
}

Vector集合

线程安全的类(底层结构:数组,查询快,增删慢)

特有功能:

public void addElement(E obj)将指定的元素添加Vector集合中(默认追加)
public Enumeration elements():获取枚举组件接口----->类似于Collection集合的Iterator iterator()
Enumeration接口
boolean hasMoreElements() 判断是否有更多的元素 ----->类似于Iterator里面的boolean hasNext()
E nextElement() :获取下一个元素 ----->类似于Iterator里面的E next()
public E elementAt(int index):通过索引值获取元素 ---->类似List集合的E get(int index)
int size():获取集合元素数

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

        //创建Vector集合
        Vector<String> v = new Vector<>() ;
        System.out.println(v) ;

        // public void addElement(E obj)将指定的元素添加Vector集合中(默认追加)
        v.addElement("hello") ;
        v.addElement("hello") ;
        v.addElement("world") ;
        v.addElement("javaEE") ;
        System.out.println(v);
        System.out.println("------------------------------------------------------") ;
        // public E elementAt(int index):通过索引值获取元素   ---->类似List集合的E get(int index)
        //int size():获取集合元素数
        //特有遍历方式1
        for(int x = 0 ; x < v.size() ;x++){
            String s = v.elementAt(x);
            System.out.println(s);
        }
        System.out.println("------------------------------------------------------") ;
        //特有遍历方式2:
        /*
        public Enumeration<E> elements():获取枚举组件接口----->类似于Collection集合的Iterator iterator()
 *              Enumeration接口
 *
 *                          boolean hasMoreElements() 判断是否有更多的元素 ----->类似于Iterator里面的boolean hasNext()
 *                          E  nextElement() :获取下一个元素              ----->类似于Iterator里面的E next()
         */
        Enumeration<String> en = v.elements();
        while(en.hasMoreElements()){
            String s = en.nextElement();
            System.out.println(s);
        }
    }
}

Vector集合遍历的特有方式有哪些

方式1:
Enumrmation elements() ---->类似于 Iterator iterator()
接口
public boolean hasMoreElements() :是否有更多的元素----->public boolean hasNext()
public E nextElement() ------------->public E next()
方式2:
普通for循环:size()和public E elementAt(int index)通过角标获取元素

LinkedList

线程不安全,不同步,执行效率高

底层数据结构: 线程结构之链表,查询慢,增删快!

在这里插入图片描述

特有功能:

添加元素
public void addFirst(E e) 将指定的元素添加到链表的开头
public void addLast(E e) 将指定的元素添加到链表的末尾
public E getFirst():获取第一个元素
public E getLast():获取最后一个元素
public E removeFirst():删除第一个并返回第一个元素
public E removeLast():删除最后一个元素并返回

public class LinkedListDemo {
    public static void main(String[] args) {
        //创建一个链表
        LinkedList<String> lk = new LinkedList<>() ;
        //添加字符串
        lk.add("hello") ;
        lk.add("world") ;
        lk.add("java") ;
        System.out.println(lk) ;
        /*
         public void addFirst(E e) 将指定的元素添加到链表的开头
 *              public void addLast(E e) 将指定的元素添加到链表的末尾
 *              public E getFirst():获取第一个元素
 *              public E getLast():获取最后一个元素
 *              public E removeFirst():删除第一个并返回第一个元素
 *              public E removeLast():删除最后一个元素并返回
         */
        lk.addFirst("JavaEE"); ;
        lk.addLast("Android");
        System.out.println(lk);
        System.out.println(lk.getFirst());
        System.out.println(lk.getLast());
        System.out.println(lk.removeFirst());
        System.out.println(lk);
    }
}

使用LinkedList来模拟栈结构特点:先进后出

public class LinkedListTest {
    public static void main(String[] args) {
        //测试
        MyStack<String> my = new MyStack<>() ;//本质创建了LinkedList集合对象
        my.addElement("hello") ;
        my.addElement("world") ;
        my.addElement("javaee") ;
        my.addElement("android") ;

        //第一次获取
      /*  System.out.println(my.getElement());
        //第二次获取
        System.out.println(my.getElement());
        //第三次
        System.out.println(my.getElement());
        //第四次
        System.out.println(my.getElement());
        System.out.println(my.getElement());*/
        while (!my.myStackIsEmpty()){
            //如果不为,才获取元素
            System.out.println(my.getElement());
        }
    }
}

//自定义一个类MyStack,模拟栈--->里面使用LinkedList集合的功能
// interface 接口名<T>{}
//class 类名<T>{}
//public <T> T 方法名(形式参数列表)  泛型定义在方法上
public class MyStack<T> {//MyStack<String>
    //提供一个成员变量
    private LinkedList<T> lk ;
    //无参构造方法
    public MyStack(){
        //创建一个LinkedList集合对象
        lk = new LinkedList<>() ;

    }
    //定义一个功能,添加元素
    public void addElement(T t){
        //使用LinkedList集合的功能
        lk.addFirst(t) ;
        //System.out.println(lk);
    }
    //获取元素
    public T getElement(){
        return lk.removeFirst() ;//删除第一个并返回 --->相当于LinkedList的pop()弹栈
    }

    //提供一个判断
    public boolean myStackIsEmpty(){
        return lk.isEmpty() ;
    }

}

Set集合

元素唯一的 默认情况使用HashSet进行实例(创建对象)

HashSet的底层依赖于HashMap(哈希表结构),元素唯一,迭代顺序无法保证的!
HashSet集合保证元素唯一—底层依赖HashMap的put方法---->依赖于hashCode()/equals(),而现在存储String类型,重写了equals和hashCode(),保证元素唯一!

public class HashSetDemo {
    public static void main(String[] args) {
        //创建HashSet集合对象
        HashSet<String> hs = new HashSet<>() ;

        //添加元素
        hs.add("hello") ;
        hs.add("hello") ;
        hs.add("world") ;
        hs.add("world") ;
        hs.add("java") ;
        hs.add("java") ;
        hs.add("javaee") ;

        //遍历
        for(String s:hs){
            System.out.println(s);
        }
    }
}

使用HashSet集合存储自定义类型,如何保证元素唯一?
Set集合的应用:
	1)使用Random产生10个随机数,存储到集合中,保证元素唯一!HashSet<Integer>
	2)针对单例集合排序(给定一个主要条件),使用TreeSet<E>
public class HashSetTest {
    public static void main(String[] args) {
        //创建HashSet
        HashSet<Student> hs = new HashSet<>() ;


        //创建学生对象
        Student s1 = new Student("高圆圆",32) ;
        Student s2 = new Student("高圆圆",32) ;
        Student s3 = new Student("高圆圆",32) ;
        Student s4 = new Student("文章",35) ;
        Student s5 = new Student("文章",32) ;
        Student s6 = new Student("赵又廷",36) ;
        Student s7 = new Student("赵又廷",36) ;
        Student s8 = new Student("马伊琍",38) ;

        hs.add(s1) ;
        hs.add(s2) ;
        hs.add(s3) ;
        hs.add(s4) ;
        hs.add(s5) ;
        hs.add(s6) ;
        hs.add(s7) ;
        hs.add(s8) ;

        for(Student s: hs){
            System.out.println(s);
        }
    }
}

TreeSet集合

底层基于TreeMap<K,V>,它是一个红黑树(red-black-tree)
有自然排序/比较器排序
在这里插入图片描述

构造方法:

public TreeSet():创建一个空的树,元素是按照自然排序顺序,里面的元素必须要实现Comparable接口
现在使用TreeSet存储Integer类型的元素

结论:

要实现自然排序,那么使用TreeSet的无参构造方法,而且存的类型一定要实现Comparable接口,重写compareTo(T t)方法,完成比较

public class TreeSetDemo {
    public static void main(String[] args) {
        //创建一个TreeSet集合
        // public TreeSet():创建一个空的树,元素是按照自然排序顺序,里面的元素必须要实现Comparable接口
        TreeSet<Integer> ts = new TreeSet<>() ;

        //添加元素
        ts.add(17) ;
        ts.add(19) ;
        ts.add(20) ;
        ts.add(22) ;
        ts.add(18) ;
        ts.add(18) ;
        ts.add(23) ;
        ts.add(23) ;
        ts.add(16) ;
        ts.add(24) ;
        ts.add(24) ;

        //遍历
        for(Integer i :ts){
            System.out.println(i);
        }

    }
}

应用

学生类

public class Student  implements Comparable<Student>{
    private String name ;
    private int age ;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    //重写方法
    @Override
    public int compareTo(Student s) {
        //存储s1-s8  s1就是作为根节点
        //主要条件:
        // 按照学生的年龄从小到大排序
      /*  int num = this.age -s.age ;
        //次要条件(自己分析):如果年龄相同,还要比较姓名是否一样的
        int num2 = (num==0)?(this.name.compareTo(s.name)):num;
        return num2;*/


        //主要条件:按照学生的姓名长度比较: 从小到大比较
        int num = this.name.length() - s.name.length() ;
        //次要条件:如果num==0,姓名长度一样,比较姓名内容是否一样
        int num2 = (num==0)?(this.name.compareTo(s.name)):num;
        //次要条件2:如果姓名长度一样,姓名内容也一样,还要比较年龄是否一样
        int num3 = (num2==0)?(this.age-s.age):num2;
        return num3 ;


    }
}

测试类

/* 存储的Student类型实现Comparable,完成自然排序!
 *                  排序条件(主要条件)
 *                          按照学生的年龄从小到大排序
 *
 *                         自己的分析次要条件:
 *
 *
 *  使用TreeSet<Student>,按照自然排序排序
 *              主要条件:
 *                      按需学生的姓名的长度从小到大比较
 *
 *               次要条件:长度相同,比较姓名内容是否相同
 *
 *
 * 键盘录入5个学生姓名,数学成绩,英语成绩,语文成绩 ,按照学生的总分从高到到低排序!
 *
 *
 */
public class TreeSetDemo {
    public static void main(String[] args) {
        //创建TreeSet集合
        TreeSet<Student> ts = new TreeSet<Student>() ;//无参构造方法,自然排序

        //创建一堆学生
        Student s1 = new Student("gaoyuanyuan",32) ;
        Student s2 = new Student("gaoyuayuan",32) ;
        Student s3 = new Student("liushishi",36) ;
        Student s4 = new Student("wangbaoqi",36) ;
        Student s5 = new Student("wenzhang",28) ;
        Student s6 = new Student("wenzhang",28) ;
        Student s7 = new Student("mabaoguo",65) ;
        Student s8 = new Student("mabaoguo",56) ;
        Student s9 = new Student("gaoyuanyuan",35) ;
        Student s10 = new Student("zhangwen",35) ;

        //添加
        //Student类没有实现自然排序接口
        //java.lang.ClassCastException: com.qf.treeset_05.Student cannot be cast to java.lang.Comparable
        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        ts.add(s7) ;
        ts.add(s8) ;
        ts.add(s9);
        ts.add(s10);

        //遍历
        for(Student s:ts){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}

存储的Student类型实现Comparable,完成比较器排序
排序条件(主要条件)
按照学生的年龄从小到大排序
比较强排序:
TreeSet有参构造方法
public TreeSet(Comparator<? super E> comparator) 按照比较强排序

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

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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


}

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

        //创建一个TreeSet集合
        //public TreeSet(Comparator<? super E> comparator) 按照比较强排序
        //比较器排序方式1:自定义一个类实现Comparator接口
       // MyComparator my = new MyComparator() ;  //具体类对象
        //Comparator<Student> my = new MyComparator() ;  //接口多态
       // TreeSet<Student> ts = new TreeSet<>(my) ;

        //方式2:public TreeSet(Comparator<? super E> comparator) 按照比较强排序,使用接口匿名内部类

        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //按照学生的年龄从小到大排序(主要条件)
                //s1---->this
                //s2---->s
                int num = s1.getAge() - s2.getAge() ;
                //次要条件:年龄相同,比较姓名是否一致
                int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ;
                return num2;
            }
        }) ;
        //创建学生对象
        Student s1 = new Student("wenzhang",25) ;
        Student s2 = new Student("wenzhang",25) ;
        Student s3 = new Student("gaoyuanyuan",25) ;
        Student s4 = new Student("luozhixiang",32) ;
        Student s5 = new Student("gaoyuanyuan",22) ;
        Student s6 = new Student("mayili",22) ;
        //添加
        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        for(Student s:ts){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}

//自定义类实现Comparator,完成比较器排序
public class MyComparator  implements Comparator<Student> {

    @Override
    public int compare(Student s1, Student s2) {
        //按照学生的年龄从小到大排序(主要条件)
        //s1---->this
        //s2---->s
        int num = s1.getAge() - s2.getAge() ;
        //次要条件:年龄相同,比较姓名是否一致
        int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ;
        return num2;
    }
}

LinkedList集合的特有功能

addFirst():添加链表的开头
addLast():添加链表的末尾
public E removeFirst()删除并返回第一个元素
public E removeLast()删除并返回最后一个元素
public E getFirst():获取第一个元素
public E getLast():获取最后一个元素

如果需求 大量 “写"的操作,采用LinkedList
大量"读"的操作,默认使用ArrayList,大量"读”,考虑线程 使用Vector

Map集合

需求:
通过学生的学号sid,获取学生的信息(姓名…)
现在使用单列集合Collection</>—>List /Set
List,本身就是将整个对象存储进去了,获取方式直接获取学生数据,遍历---->判断sid是多少
所以Java提供 Map<K,V> 键值对(映射项),一个键(必须唯一)对应一个值(值可以重复)

KeyValue ---->散列表结构(哈希表)
1张三
2李四
3王五
4张三

遍历方式

通用方式 获取所有的键,通过键找值!

应用范围:

HashMap---->存储 和 获取 (默认使用)
TreeMap---->存储—获取(按照排序规则排序)
Map---->称为 “实体”
Map<Integer,Product>

Map(针对键有效,键必须唯一!)的基本功能

添加:

V put(K key, V value):添加键值对元素,返回值什么意思?
map针对键有效,键如果唯一的,返回是null;
如果重复,将后面的键对应的值把前面的值覆盖了,返回第一次键对应的值

删除:

V remove(Object key):删除键,返回键对应的值
void clear():暴力删除,将map清空掉

判断:

boolean containsKey(Object key):判断Map集合是否包含指定的键,包含返回true,否则false
boolean containsValue(Object value):判断Map集合是否包含指定的值,包含则返回true,否则false
boolean isEmpty() :判断集合是否为空

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

        //创建Map集合---子实现类HashMap
        Map<String,String> map  = new HashMap<>() ;
        System.out.println(map) ;

        //  V put(K key, V value):添加键值对元素,返回值什么意思?
        //添加
      //  String value = map.put("文章", "马伊琍");
       // System.out.println(value);
       // String value2 = map.put("文章", "姚笛") ;
      //  System.out.println(value2);
        //String value3 = map.put("王宝强", "马蓉");
       // System.out.println(value3);
        map.put("文章", "马伊琍");
        map.put("文章", "姚笛") ;
        map.put("王宝强", "马蓉");
        map.put("黄晓明","babay") ;
        map.put("陈玄风","梅超风") ;
        System.out.println(map);

        System.out.println("-----------------------------------------------") ;
        //V remove(Object key):删除键,返回键对应的值
        // void clear():暴力删除,将map清空掉
        System.out.println(map.remove("陈玄风"));
        //map.clear();
        //System.out.println(map);
        System.out.println("-----------------------------------------------") ;
//        boolean containsKey(Object key):判断Map集合是否包含指定的键,包含返回true,否则false (使用居多)
//        boolean containsValue(Object value):判断Map集合是否包含指定的值,包含则返回true,否则false
//        boolean isEmpty() :判断集合是否为空
        System.out.println(map.containsKey("马保国"));
        System.out.println(map.containsKey("黄晓明"));
        System.out.println(map.containsValue("马蓉"));
        System.out.println(map.containsValue("孙俪"));
        System.out.println(map.isEmpty()) ;


    }
}

遍历Map集合的方式

1)获取所有的键的集合 Set keySet() (通用的遍历方式) —>“获取所有的丈夫”,丈夫自己妻子
结合 V get(Object key):通过键找值
2)Set<Map.Entry<K,V>> entrySet() :获取Map结合的键值对对象 ---->“获取所有结婚”,找丈夫,找妻子
HashMap---->put方法---->依赖于hashCode()+equals()方法 能够保证键唯一!
存储String,String类型重写了hashCode()+equals()方法,比较键的字符串内容是否相同!

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

        //创建Map集合
        Map<String,String> map = new HashMap<>() ;

        //添加元素
        map.put("郭靖","黄蓉") ;
        map.put("杨过","小龙女") ;
        map.put("陈玄风","梅超风") ;
        map.put("令狐冲","任盈盈") ;
        map.put("郭靖","高圆圆") ;

        /**
         * 1)获取所有的键的集合 Set<K> keySet()    (通用的遍历方式)      --->"获取所有的丈夫",丈夫自己妻子
         *           结合    V get(Object key):通过键找值
         */
       /* Set<String> keySet = map.keySet() ;
        for(String key:keySet){
            //通过键获取值
            String value = map.get(key);
            System.out.println(key+"---"+value) ;
        }*/
        /**
         * 2)Set<Map.Entry<K,V>> entrySet() :获取Map结合的键值对对象    ---->"获取所有结婚",找丈夫,找妻子
         */
        Set<Map.Entry<String, String>> entry = map.entrySet() ;
        //遍历所有映射项(一个键->一个值)
        for(Map.Entry<String, String> en:entry){
            //K getKey():通过键值对对象,获取键
            //K getKey():通过键值对获取值
            String key = en.getKey();
            String value = en.getValue();
            System.out.println(key+"---"+value) ;

        }


    }
}

HashMap<K,V> 存储键值对元素,保证K唯一,根据的类型有关系
如果K是自定义类型,
HashMap<Student,String> ,考虑保证学生对象唯一!
Key:Student类型
Value:String类型
要针对键有效,需要键的类型,需要重写equals()和hashCode()
equals():比较内容是否相同, hashCode():比较每一个成员信息的哈希码值是否一样

public class MapDemo3 {
    public static void main(String[] args) {
        //创建HashMap集合对象
        HashMap<Student,String> map = new HashMap<>() ;

        //创建学生对象
        Student s1 = new Student("唐伯虎",30) ;
        Student s2 = new Student("祝枝山",32) ;
        Student s3 = new Student("梁山伯",25) ;
        Student s4 = new Student("梁山伯",25) ;
        Student s5 = new Student("苏轼",36) ;
        Student s6 = new Student("苏轼",36) ;

        //给map集合添加元素
        map.put(s1,"明朝");
        map.put(s2,"明朝");
        map.put(s3,"宋朝");
        map.put(s4,"唐朝");
        map.put(s5,"宋朝");
        map.put(s6,"宋朝");

        //遍历Map集合
        Set<Student> keySet = map.keySet();
        for(Student key:keySet){
            //通过键获取值
            String value = map.get(key);
            System.out.println(key.getName()+"---"+key.getAge()+"---"+value) ;
        }
    }
}

TreeMap<K,V>–>针对键有效,排序(自然排序/比较器排序)

构造方法:

public TreeMap():自然排序
public TreeMap(Comparator<? super K> comparator):比较器排序
如果键是自定义类型,键必须唯一,而且需要有排序规则!

按照学生的年龄从小到大排序

public class Employee {
    private String name ; //姓名
    private int age ;



    public Employee() {
    }

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

    //重写equals and hashcode
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Employee student = (Employee) o;

        if (age != student.age) return false;
        return name.equals(student.name);
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

//TreeSet<Emplyee,String> 来按照学生的年龄从小到大排序(主要条件)
public class TreeMapDemo {
    public static void main(String[] args) {
        //创建TreeMap集合对象,按照比较器排序(年龄从小到大排序)
        TreeMap<Employee,String> tm = new TreeMap<>(new Comparator<Employee>() {
            //比较器的比较
            @Override
            public int compare(Employee e1, Employee e2) {
                //年龄从小到大排序
                int num = e1.getAge() - e2.getAge() ;
                //次要条件:年龄相同,比较姓名是否一致
                int num2 = (num==0)?(e1.getName().compareTo(e2.getName())):num;
                return num2;
            }
        }) ;
        //存储员工对象
        Employee e1 = new Employee("zhangsan",20) ;
        Employee e2 = new Employee("wangwu",19) ;
        Employee e3 = new Employee("zhaoyouting",28) ;
        Employee e4 = new Employee("wenzhang",28) ;
        Employee e5 = new Employee("zhangsanfeng",35) ;
        Employee e6 = new Employee("zhangsanfeng",35) ;
        Employee e7 = new Employee("mayili",39) ;
        Employee e8 = new Employee("mayili",30) ;

        tm.put(e1,"9527") ;
        tm.put(e2,"9528") ;
        tm.put(e3,"dev001") ;
        tm.put(e4,"9527") ;
        tm.put(e5,"test001") ;
        tm.put(e6,"test002") ;
        tm.put(e7,"9528") ;
        tm.put(e8,"9527") ;

        //遍历
        //获取所有的键
        Set<Employee> keySet = tm.keySet();
        for(Employee e:keySet){
            //键获取值
            String value = tm.get(e);
            System.out.println(e.getName()+"--"+e.getAge()+"--"+value);
        }

    }
}

java.util.Collections:针对集合操作工具类

常用的方法

二分搜索法,在指定List集合中查询指定元素第一次出现索引值 (集合的元素有序)
public static int binarySearch(List<? extends Comparable<? super T>> list,T key)

public static T max(Collection<? extends T> coll):针对Collection集合获取最大值(自然顺序比较获取最大值)

public static T min(Collection<? extends T> coll):针对Collection集合获取最小值(自然顺序比较获取最小值)

public static void reverse(List<?> list):将List集合的元素反转

public static void shuffle(List<?> list):针对List集合随机置换

public static <T extends Comparable<? super T>> void sort(List list):针对List集合按照自然顺序排序

public static <T extends Comparable<? super T>> void sort(List list,Comparator com):
针对List集合按照比较器进行排序

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

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

        //创建一个List集合
        List<Integer> list = new ArrayList<>() ;
        list.add(10) ;
        list.add(5) ;
        list.add(25) ;
        list.add(15) ;
        list.add(12) ;
        list.add(35) ;
        System.out.println(list);
         //public static <T extends Comparable<? super T>> void sort(List<T> list):针对List集合按照自然顺序排序
        Collections.sort(list) ;
        System.out.println(list);
        // public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key)
        System.out.println(Collections.binarySearch(list,12));
        System.out.println(Collections.binarySearch(list,120));
        System.out.println("-----------------------------------------------") ;
        System.out.println(Collections.max(list));
        System.out.println(Collections.min(list));
        Collections.shuffle(list) ;
        System.out.println(list);
        System.out.println("---------------------------------------------") ;
        //使用List集合存储员工,然后按照员工的年龄从小到大排序(主要条件)
        //public static <T extends Comparable<? super T>> void sort(List<T> list,Comparator<T> com):
        List<Employee> ls  = new ArrayList<>() ;
        //存储员工对象
        Employee e1 = new Employee("zhangsan",20) ;
        Employee e2 = new Employee("wangwu",19) ;
        Employee e3 = new Employee("zhaoyouting",28) ;
        Employee e4 = new Employee("wenzhang",28) ;
        Employee e5 = new Employee("zhangsanfeng",35) ;
        Employee e6 = new Employee("zhangsanfeng",35) ;
        Employee e7 = new Employee("mayili",39) ;
        Employee e8 = new Employee("mayili",30) ;
        ls.add(e1) ;
        ls.add(e2) ;
        ls.add(e3) ;
        ls.add(e4) ;
        ls.add(e5) ;
        ls.add(e6) ;
        ls.add(e7) ;
        ls.add(e8) ;

        //按照员工的年龄从小到大
        Collections.sort(ls, new Comparator<Employee>() {
            //比较器实现
            @Override
            public int compare(Employee e1, Employee e2) {
                int num = e1.getAge() - e2.getAge() ;
                int num2 = (num==0)?(e1.getName().compareTo(e2.getName())):num ;
                return num2;
            }
        });

        //遍历
        for(Employee e:ls){
            System.out.println(e.getName()+"---"+e.getAge());
        }
    }
}

#模拟斗地主
在这里插入图片描述

/**
 * 使用集合 来完成 斗地主的洗牌和发牌,看牌(定义一个功能)
 * 斗地主:三个玩家----54张牌 ,底牌3张
 *      不考虑三个玩家的手上牌有序的!
 *   分析:
 *          1)牌盒-------------->ArrayList<String>
 *          2)装牌
 *                      点数数组  = {"A","2","3"......,"10","J","Q","K"}
 *                      花色数组= {"♥","♠","♣","♦"}
 *             将每一个点数和花色拼接(concat(String str))到一块  "牌"
 *             将  "牌"添加牌盒中
 *             单独添加"小王","大王"
 *          3)洗牌-------->将ArrayList随机置换 ---Collections的public static void shuffle(List<?> list):针对List集合随机置换
 *          4)发牌:
 *                  三个玩家---->看成三个集合,每一个玩家就是ArrayList<String>
 *                    底牌--->也可以成集合
 *                   A--->B--->C
 *                 规律:
 *                      遍历ArrayList集合,里面去判断
 *                      for(int x = 0 ; x <牌盒集合.size();x++ ){
 *
 *                          if(x%3==0){
 *                              //玩家1  add(大集合的集合.get(x))
 *                          }else if(x%3==1){
 *                              //玩家2
 *                          }else if(x%3==2){
 *                              ...
 *                          }
 *                      }
 *                   调用用看牌的方法("玩家1",玩家1的集合) ;
 *                   调用用看牌的方法("玩家2",玩家2的集合) ;
 *                   调用用看牌的方法("玩家3",玩家3的集合) ;
 *             5)看牌
 *              定义一个方法
 *                      public static void loolPoker(String name,ArrayList<String> array){
 *                          //xxx的牌是
 *                                  将牌全部遍历出来,展示信息
 *
 *                      }
 *
 *
 */
public class PokerDemo {
    public static void main(String[] args) {

        // 1)牌盒-------------->ArrayList<String>
        ArrayList<String> pokerBox  = new ArrayList<>() ;
        //2)装牌
        //2.1)创建一个点数数组
        String[] numbers = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"} ;
        //2.2)创建一个花色数组
        String[] colors = {"♥","♠","♣","♦"} ;
        //2.3)将花色和点数拼接
        for(String color:colors){ //花色
            for(String number:numbers){//点数
                String poker = color.concat(number); //牌
                //添加pokerBox中
                pokerBox.add(poker) ;
            }
        }
        //添加小王和大王
        pokerBox.add("小王") ;
        pokerBox.add("大王") ;

        System.out.println(pokerBox) ;

        //3)洗牌-------->将ArrayList随机置换
        Collections.shuffle(pokerBox) ;
        System.out.println(pokerBox);

        //4)发牌
        //需要三个玩家,以及底牌---看成ArrayList
        ArrayList<String> player1 = new ArrayList<>() ;
        ArrayList<String> player2 = new ArrayList<>() ;
        ArrayList<String> player3 = new ArrayList<>() ;
        ArrayList<String> diPai = new ArrayList<>() ;
        /**
         *  三个玩家---->看成三个集合,每一个玩家就是ArrayList<String>
         *                      底牌--->也可以成集合
         *                     A--->B--->C
         */
        //遍历牌盒的里面的所有牌
        for(int x = 0 ; x < pokerBox.size()  ;x++){//0,53
            //规律:
            //底牌
            if(x>= pokerBox.size()-3){
                //给底牌添加元素
                diPai.add(pokerBox.get(x)) ;
            }else if(x%3==0){
                //这种情况里面的牌的给玩家1
                player1.add(pokerBox.get(x)) ;
            }else if(x%3==1){
                player2.add(pokerBox.get(x)) ;
            }else {
                //玩家3
                player3.add(pokerBox.get(x)) ;
            }
        }

        //看牌
        //三个玩家都可以看牌,可以看底牌
        lookPoker("高圆圆",player1) ;
        lookPoker("张杨",player2) ;
        lookPoker("赵又廷",player3) ;
        lookPoker("底牌",diPai) ;




    }

    //定义一个看牌的方法
    public static void lookPoker(String name,ArrayList<String> array){
        System.out.print(name+"的牌是:\t" ) ;
        //遍历牌(ArrayList)
        for(String s:array){
            System.out.print(s+" ") ;
        }
        System.out.println();
    }
}

面试题

一、数组中没有length(),字符串有没有length(),集合中没有有length()?

1.数组 没有length(),length属性 数组对象.length

2.字符串有length(),

3.集合没有,获取集合中 元素数 size()

二、String s = new String(“hello”) ; 和 String s = “hello” ; 有什么区别?分别创建了几个对象?

​ 前者:在堆内存中开辟空间,然后字符串值常量—指向常量池, 两个对象

​ 后者:推荐的方式,直接常量赋值,直接在常量池中找,有就返回地址,没有,开辟常量空间!

三、String s1 = “hello”; 和 String s2 = “hel” ;按照字典顺序比较,它的结果是多少? 考察的就是compareTo的源码

public int compareTo(String anotherString):两个字符串按照字典顺序比较!
两个字符串进行字典顺序比较,先算出长度,取出最小值,然后比较每一个字符,如果这俩个字符串的第一个字符都不相同

使用前面的字符和后面的的字符进行相减(ASII码表的值相减)

如果长度的最小值,在循环遍历两个字符串的每一个字符之前,都相同,直接是两个字符串长度相减!

public class StringTest {
public static void main(String[] args) {
    String s1 = "hello";
    String s2 = "hel" ;
    String s3 = "abc" ;
    System.out.println(s1.compareTo(s2));
    System.out.println(s1.compareTo(s3));
}
}

四、String和StringBuffer/StringBuilder的区别?

String:是一个常量,一旦被赋值,其值不能被更改 ,不可变的字符序列!
	作为形式参数,形式参数的改变不影响实际参数(和基本类型作为形式参数传递的效果一致 ,特殊的引用类型)
StringBuffer:支持可变的字符串徐磊,线程安全的类--->同步的--->执行效率低
StringBuffer的大部分功能--->synchronzied:同步锁(悲观锁)(多线程去讲)
	作为形式参数,形式参数的改变直接影响实际参数
StringBuilder:和StringBuffer具备相互兼容的API,线程不安全的类---不同步的---->执行效率高
	单线程程序(只考虑效率)中,使用StringBuilder去替代StringBuffer
	多线程环境下(要考虑安全),使用StringBuffer

五、final,finalize,finally有什么区别?

final:状态修饰符 表示最终的无法更改的

	修饰类,类不能被继承
	修饰符成员方法,方法不能被重写
	修饰变量,此时常量

finalize是一个方法:Object类的方法---->主要垃圾回收器回收没有更多引用的对象,来释放内存空间

finally:关键字:  捕获异常标准格式 :try{

	//可能出现问题的代码

	}catch(异常类名 对象名){

	//处理异常
	}finally{
	//释放系统资源(Java底层语言都是c)
	//Io流(创建文件/流对象都需要关闭) /jdbc(连接对象,执行对象,查询对象都需要close)
	}

六、String,StringBuffer,StringBuilder的区别

String
	String是一个常量,支持不可变的字符序列,一旦被赋值其值不能被更改!
	String作为形式参数,特殊的引用类型,形式参数的改变不影响实际参数(和基本类型一致的)

StringBuffer
	支持可变的字符序列,字符串缓冲区(容器,可以存储任意类型的数据--字符序列),最终容器--返回String
	线程安全的类(几乎所有成员方法有个关键字 synchronized:同步锁)--->多线程环境下使用居多
	除了String之外的引用类型,作为形式参数,形参的改变直接影响实际参数!

StringBuilder
	和StringBuffer具有兼容的API;线程不安全的类---->不同步--->执行效率高
	单线程环境下使用StringBuilder去替代StringBuffer

七、面试题 集合和数组的区别?

1)长度区别
	数组长度固定的
	集合长度是可变的
2)存储数据类型的区别
	数组:皆可以存储基本类型,也可以存储引用类型数据,但是这些数据的类型必须一致!
	举例:
	int[] arr = new int[3] ;
	Student[] studenets = new Student[5] ;
	集合
	只能存储引用类型数据,如果集合不带泛型,那么本身就可以存储任意用类型数据
	举例
	Collection<引用类型>
3)存储元素的区别
	数组:存储必须一种类型的元素
	单一类型
	集合:存储任意引用类型的元素
	多种类型

八、List集合三个子实现类特点

ArrayList:
	底层数据结构是数组,查询快,增删慢
	线程不安全,不同步----执行效率高
	扩容机制是1.5倍
Vector
	底层数据结构是数组,查询快,增删慢
	线程安全,同步--->执行效率低(多线程环境下使用)
LinkedList
	底层数据结构是链表,查询慢,增删快
	线程不安全,不同步--->执行效率高
	应用场景:添加操作---每次将数据添加集合的前面/删除末尾元素

九、Map和Collection的区别 ?

Collection:单例集合,只能存储一种引用类型数据 遍历方式和Map不同;

Collection集合的应用范围大:

ArrayList

Vector

LinkedList

它里面的部分集合和Map有关联(HashSet—>依赖HashMap / TreeSet---->依赖于TreeMap)

Map<K,V>,双列集合---->可以存储键值对(“夫妻对”)

十、Java能够直接创建多线程吗?

创建线程---->需要创建进程---->需要使用系统资源创建进程
Java是不能够直接操作系统资源的,底层语言C是可以操作系统的
Jdk提供了Thread类,里面有个start()---->执行线程—底层非Java语言实现的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱学Java的小宇宙

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值