总结-第一阶段-第四周

文章介绍了Java中的集合框架,包括String、ArrayList、HashSet、LinkedList等数据结构的使用,如添加、删除、遍历等操作,以及它们在多线程环境下的表现。此外,文章还讨论了集合的去重、转换、排序等常见问题,提供了相关的面试题和解答。
摘要由CSDN通过智能技术生成

选择排序

1、使用0角标对应的元素和后面角标对应的元素依次比较,第一次比较完,最小值出现在最小索引处

2、第二次使用1角标对应的元素和后面的元素进行比较,比较完后,第二小的值出现在第二个索引处

3、总共比较的次数:数组长度 -1

 	for(int x = 0 ; x < array.length-1;x++){ //外层比较次数
        for(int y = x +1; y< array.length ; y ++){ //里面元素比较
             //后面元素比较前面元素小,小的往前放
            if(array[y] < array[x]){
                    int temp = array[y] ;
                    array[y] = array[x] ;
                    array[x] = temp ;
                }	}	}	}          

在这里插入图片描述

Object类

object重点功能

1、getClass()    获取正在运行的类; 返回字节码文件对象(类的全限定名称)
	Student s1 = new Student() ;
	Class c1 = s1.getClass() ;
	 System.out.println(c1) ;//class com.qf.object_01.Student  (class标记类  包名.类名-->类的全限定名称)

2、toString()    默认返回 :全类名+@+哈希值的十六进制。子类往往重写该方法,用以返回对象的字符串表示形式。
	Student s1 = new Student("高圆圆",44) ;
	s1.toString();

3、hashCode()     返回对象的哈希码值,不同的对象,它的哈希码值不同。 (理解为 "地址值",它不是实际意义的地址值----通过哈希算法算出来的)。
该方法往往和equals()一起被重写,用以比较自定义的类的对象属性是否相等。

4、protected Object clone() throws CloneNotSupportedException  克隆方法:创建并返回此对象的"副本"----前提是自定义的类型必须实现Cloneable接口,否则无法克隆
	 Student s1 = new Student() ;
	 Object o = s1.clone(); 
	 class Student implements Cloneable()

5、finalize()  Object类的垃圾回收方法
 protected void finalize()throws Throwable--跟gc垃圾回收器有关系

Cloneable接口:某个类如果能够实现这个接口,那么这个类对象就可以克隆
如果一个接口没有成员变量,连成员方法都没有,将这类接口称为"标记接口"
Object类的clone方法里面被 native:本地方法---非Java语言实现

面试题:在Java中获取一个类的字节码文件对象的方式有几种

1、public final Class getClass(): 获取正在运行的类;  (返回字节码文件对象)
	 Class c1 = s1.getClass() ;
2、在Java中任意类型的class属性   举例: Class c = 类名.class
	 Class c3= Student.class ;
3、Class类提供的一个静态方法  
  public static Class forName(String classPathName)throws ClassNotFoundException :参数为当前类的全限定名称
	 Class c4 = Class.forName("com.qf.object_01.Student") ;

面试题: ==和equals的区别

1、 ==连接的是两个基本数据类型:比较的是数据值是否相等

​ ==连接的是引用类型,比较的是引用类型的地址值是否相等

2、 equals: Object的 equaels()方法默认比较的是两个对象的地址值相同。

如果要比较成员信息的内容是否相同,必须重写Object的equals方法以及hashCode(),重写之后比较的是内容是否相同

equals重写之后,是比较里面的每一个成员信息是否一样,如果都一样。还有比较两个成员对应的hashCode()是否一样,如果一样,是同一个人

看程序,写结结果
  考点:
      ==和equals的区别:
      ==:连接的是两个引用类型的数据,比较的是两个对象的地址是否相同
      Object的equals():默认比较的是两个对象的地址值是否相同,子类重写了equals(),就比较两个对象的内容是否相同
      字符串常量相加:先相加,然后看结果,是否在常量池中,如果有,直接返回值地址;否则开空间
	字符变量相加:先在常量池开辟空间,然后在操作;

public class StringDemo3 {
    public static void main(String[] args) {
        String s1 = "hello" ;
        String s2 = "world" ;
        String s3 = "helloworld" ;
        System.out.println((s1+s2)==s3) ;
        System.out.println((s1+s2).equals(s3)) ;//String类重写了Object的equals方法,只管字符串内容是否一样
        System.out.println("----------------------------") ;
        System.out.println(("hello"+"world")==s3) ;//常量先相加,然后常量池中找,存在返回地址;否则常量池开空间
        System.out.println(("hello"+"world").equals(s3)) ;//比较内容是否相同
    }
}

Scanner类

java.util.Scanner:文本扫描器(键盘录入数据的)
 	构造方法:
      public Scanner(InputStream source):
创建一个文本扫描器对象,里面参数是字节输入流,读取键盘录入的一些数据

  成员方法:
  获取功能:除过不能录入char类型之外.都可以录入
      int nextInt():录入int类型
      String next():录入字符串
      String nextLine():录入一行字符串
     ...
  判断功能
       boolean hasNextXXX()方法:判断下一个录入的是为XXX类型
 
如果先录入int,在录入String,在录入String(使用String nextLine())---String的值会被漏掉;
    解决方案:
          1)使用String  next():录入单个字符串(推荐)
          2)在使用nextLine()之前,重新创建一个新的Scanner对象;
    
创建键盘录入对象    
	Scanner sc = new Scanner(in)  ;
提示并录入数据
    System.out.println("请您输入一个数据:");
        //现在录入一个int
        //int a = sc.nextInt() ;//java.util.InputMismatchException:输入类型不匹配 :接收结果类型和录入的类型不匹配
 //boolean hasNextXXX方法():判断下一个录入的是为XXX类型
    if(sc.hasNextInt()){//如果下一个录入的是int类型
        int a = sc.nextInt() ;
         System.out.println(a);
        }else if(sc.hasNextLine()){ //录入的下一个是String类型
            String s = sc.nextLine() ;
            System.out.println(s);
        }else{
            System.out.println("没有这个类型");
        }

String类

String类:代表字符串,是一个常量,创建之后,其值不能更改。字符串的底层就是一个字符数组组成!char[]—>String。 String类特殊的引用类型,它作为方法形式参数,形式参是改变不会影响实际参数(和基本类型一致)

构造方法:
	public String():创建字符串对象
    public String(String original):将指定的字符串传进去,构造一个字符串对象
    public String(char[] value):将字符串数组---构造成String	     	 public String(char[] value,int offset,int count):将一部分字符数组转换成String
    public String(byte[] bytes)将字节数组---构造成String
    public String(byte[] bytes, int offset,int length):将一部分字节数组---构造成String

1、public String():创建字符串对象
        String s = new String() ;
        System.out.println("s:"+s) ;//打印不是地址,而空字符串,String类重写了Object类的toString()
2、 public String(String original):将指定的字符串传进去,构造一个字符串对象
        String s2 = new String("hello") ;
3、public String(char[] value):将字符串数组---构造成String
        char[] chs = {'高','圆','圆'} ;
        String s3 = new String(chs) ;
4、public String(char[] value,int offset,int count):将一部分字符数组转换成String
        String s4 = new String(chs,1,2) ;
        System.out.println("s4:"+s4);
5、public String(byte[] bytes)将字节数组---构造成String :
        byte[] bytes = {97,98,99,100,101} ;
        String s5 = new String(bytes) ;//转换过程,将每一个数据找ASII码表对应的字符值,构造成字符串
        System.out.println("s5:"+s5) ;//abcde
6、public String(byte[] bytes, int offset,int length)
        String s6 = new String(bytes,2,3) ;

面试题: 创建两种字符串的方式的区别

String s1 = “hello” ;

String s2 = new String(“hello”) ;

第一个格式:创建一个对象,直接在常量池中创建;

第二个格式:需要在堆内存开辟空间,而且指向常量池地址:内存创建了两个对象

两个都是创建字符串实例,但是推荐第一种,从内存角度考虑,消耗内存资源不严重
在这里插入图片描述

String类中常用的获取功能

String类中常用的获取功能:
		 String s = "helloworld" ;
1)public char charAt(int index) 获取指定索引值对应的字符
         char ch = s.charAt(0) ;
2)public int length()  :字符串特有功能:获取字符串长度
 		 s.length()
3)public String concat(String str):拼接功能 将指定的字符串拼接到该字符串末尾,获取新的字符串
 		 String str = s.concat("高圆圆");
4)public int indexOf(String str)返回指定字符串第一次出现索引值
         System.out.println(s.indexOf("o"));
  public int lastIndexOf(String str):返回指定子字符串最后一次出现的索引值
         System.out.println(s.lastIndexOf("o"));
5)public String[] split(String regex):字符串拆分功能
 		 String s2 = "Java-Python-C-Golang-R-Hadoop" ;
 		 String[] strArray = s2.split("-"); //字符串数组
6)截取功能
 public String substring(int beginIndex,int endIndex)
 从指定位置开始,截取到endIndex-1处结束,包前不包后
	  String ss = s.substring(5, 8);
 public String substring(int beginIndex)   从指定位置开始默认截取到末尾
      String ss = s.substring(5));

String类的常用的转换功能

String类的常用的转换功能
		String s = "中国" ;
1、 public byte[] getBytes(): 将字符串转换成字节数组 (编码:将能看懂的东西--->变成看不懂的) (使用平台默认字符集)idea设置的平台字符集:utf-8:一个中文三个字节
  		byte[] bytes = s.getBytes() ;
2、public char[] toCharArray()  :将字符串转换成字符数组  (使用居多)
  	    char[] chars = s.toCharArray();
3、public static String valueOf(常见的基本类型int/long/double/float/boolean/Object):
 String的万能方法:将上面的常用类型--转换成String
   		int i = 100 ;
   	    String result = String.valueOf(i);
4、 public String toUpperCase():将指定字符串转换成大写
		s.toLowerCase()
5、 public String toLowerCase():将指定字符串转换成小写
		s.toUpperCase()
     

String类判断功能以及其他功能

 String类判断功能以及其他功能:
 	 String s = "helloworldJavaEE" ;
1、public boolean constains(String str):判断大串中是否包指定的子字符串
	 System.out.println(s.contains("owo"));
2、public boolean equals(Object anObject)):比较两个字符串内容是否相同。区分大小写
	  System.out.println(s.equals("HelloworldJavaEE"));
3、public boolean equalsIgnoreCase(String anotherString)):忽略大小写比较
     System.out.println(s.equalsIgnoreCase("HelloworldJavaEE")); 
4、public boolean startsWith(String prefix):字符串是否以指定的前缀开头
 	 System.out.println(s.startsWith("hel"));
5、public boolean endsWith(String str):字符串是否以指定的后缀结尾
	System.out.println(s.endsWith("EE"));

其他功能:
6、public String replace(char oldChar,char newChar)替换功能:使用指定的新的字符替换以前的字符
	    System.out.println(s.replace('l','*'));
7、public String trim():删除前后两端空格
 应用场景:trim():  使用io(intput输入 Output输出)流进行 读写复制(文件内容在网络中传输)
件内容前后有一些空字符出现,获取到文件内容之后,先去trim()去除两端空格
	 	 String s1  = "    hello       ";
    	 String s2 = s1.trim() ;

面试题:字符串按照字典顺序比较结果是怎么计算的

 面试题:
String s1 = "hello" ;
String s2 = "hel" ;
s1.compareTo(s2)
这个两个字符串按照字典顺序比较结果是怎么计算的?

两个字符串--->底层是以字符数组存储-获取字符数组长度,获取长度的最小值
使用最小值作为 while循环条件, 如果没有取到最小值,一直循环
循环逻辑:
     通过获取两个字符数组的每一个字符,如果都相同,最终临界条件达到 ,两个字符数组长度相减
	如果获取到字符,如果两个字符不相等,直接是两个字符---对应的ASCII码表的值相减---直接得到字典顺序的值

compareTo源码
	final class String{
    private final char value[]; //字符数组
    public int compareTo(String anotherString) {//s1.compareTo(s2)
        int len1 = value.length; //int len1 = 获取s1字符数组.length= 5
        int len2 = anotherString.value.length; //int len2 = 获取s2字符数组.length=3
        int lim = Math.min(len1, len2); //int lim = Math.min(len1,len2)  ; //获取最小值  =3
        char v1[] = value;              //char v1[] = {'h','e','l','l','o'} ;
        char v2[] = anotherString.value; //char v2[] = {'h','e','l'} ;  //char v2[] = {'a','b','c'} ;

        int k = 0;                      //统计变量k = 0
        while (k < lim) {               //while(k < lim)  0<3                   1<3          2<3       3<3   
            char c1 = v1[k];     //char c1 = v1[0] = 'h' ;  //char c1 = v1[1] = 'e';  //char c1 = v1[2]='l';
            char c2 = v2[k];     //char c2 = v2[0] ='h' ;  //char c2 = v2[1]  = 'e' ;//char c2 = v2[2] ='l';
                                 //char c2 = v2[0] = 'a' ;

            if (c1 != c2) {             //如果两个字符不相等
                return c1 - c2;         //直接两个字符相减  --- 'h' - 'a' = 104- 97 = 7
            }
            k++;                        //k++-->1--->2--->3
        }
        return len1 - len2;     //len1-len2  ---->5-3 = 2
    }
}

String的equals方法源码
        String s1 = new String("hello") ;
        String s2  = "hello" ;
        s1.equals(s2) ;
        class String{
        private final char value[]; //value属性:是个字符数组
    public boolean equals(Object anObject) {   //
        if (this == anObject) {  //s1和s2地址值不一样
            return true;
        }
        if (anObject instanceof String) {  // if(s2 instanceOf String):s2这个变量是否为String的实例
            String anotherString = (String)anObject; //向下转型---String类型
            int n = value.length;       //s1= {'h','e','l','l','o'} ;  --获取字符数组长度5
            if (n == anotherString.value.length) {    //if(5 == 5)    //s2-=={'h','e','l','l','o'}
                char v1[] = value;                    //v1-->s1的底层字符数组
                char v2[] = anotherString.value;       //v2-->s2的底层字符数组
                int i = 0;                             //统计变量 i =  0
                while (n-- != 0) {
                                                        //i=0
                    if (v1[i] != v2[i])   {              //if(v1[0] != v2[0]) 'h' 'h'
                        return false;
                        }
                    i++;                            i++ -->1   --->
                }
                return true;                        已经取到最大索引值 ,两个字符串中字符串的字符都一样
                                                    return true;
            }
        }
        return false;
    }
}

面试题:数组中、String类在集合中有没有length()

数组中length属性,获取数组长度
String类中有length(),获取字符串长度
集合中没有。size():获取集合中元素数

String方法练习1

需求:  
	键盘录入一个字符串,将字符串的第一个字符转换成小写,其余字符转换成大写(不考虑特殊字符)

public class StringTest {
    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;
        //提示并录入字符串
        System.out.println("请输入一个字符串:") ;
        String line = sc.nextLine() ;
1)先将line的第一个字符截取出来
        String s1 = line.substring(0,1) ;
2)将s1--->转换成大写
        String s2 = s1.toUpperCase() ;
3)将line字符串 从第二个字符开始截取出来
        String s3 = line.substring(1) ;
4)将s3-->转换成小写
        String s4 = s3.toLowerCase() ;
5)将s2和s4拼接---String的concat拼接功能
        String result = s2.concat(s4) 

一步走 :链式编程
        String result =          line.substring(0,1).toUpperCase().concat(line.substring(1).toLowerCase()) ;
     

String方法练习2

 需求:
已知数组静态初始化的
int[] arr  = {24,57,69,13,98} ;
定义功能,将数组转换成String --->把数组遍历出来--->每一个元素拼接成String
public class StringTest2 {
    public static void main(String[] args) {
          //已知数组
        int[] arr  = {24,57,69,13,98} ;
        //调用将数组转换String的方法
        String result = arrayToString(arr) ;
        System.out.println(result) ;
    }
    //将转换成String
    public static String arrayToString(int[] array){
        //定义一个最终结果变量
        String s = "" ;
        s += "[" ;//或者使用字符串的concat功能
        //遍历数组
        for(int  x = 0 ; x < array.length ; x++){
            if(x==array.length-1){
                //最后一个元素
                s+=array[x] +"]" ;
            }else{
                //中间元素
                s+= array[x] +", ";
            }
        }
        return s ;
    }
}

StringBuffer

StringBuffer:字符串缓冲区,线程安全的,支持可变的字符序列

构造方法
1、 public StringBuffer():无参构造方法,里面空的字符序列,初始容量16个字符(默认容量足够大)  
	 StringBuffer sb = new StringBuffer() ;
2、 public StringBuffer(String str):将字符串构造为StringBuffer类型,容量是大小:当前的里面的字符串长度+16
	 StringBuffer sb2 = new StringBuffer("hello") ;
3、 public StringBuffer(int capacity):创建一个字符串缓冲区,指定容量大小
	 StringBuffer sb3  = new StringBuffer(50) ;
	

StringBuffer的添加/删除的功能

 StringBuffer的添加/删除的功能
      StringBuffer sb = new StringBuffer() ;
1、添加:  public StringBuffer append(任意java类型) 可以将任意类型的元素添加(在末尾追加)到字符串缓冲区中,返回值是字符串缓冲区本身
	StringBuffer sb3 = sb2.append("helloworld");	//sb.append("hello").append('A').append(true).append(100).append(new Object());
2、插入: public StringBuffer insert(int offset,任意java类型):在指定位置处的序列前面插入新的序列
		 sb.insert(5,"高圆圆") ;
3、删除: public StringBuffer deleteCharAt(int index):在指定位置处删除指定的字符,返回字符串缓冲区本身
 		sb.deleteCharAt(5) ;
4、删除: public StringBuffer delete(int start,int end):从指定位置start处开始到end-1处的字符序列删除, 返回值字符串缓冲区本身
		sb.delete(5,10) ;

StringBuffer其他功能

StringBuffer其他功能:  
替换功能
	 StringBuffer sb = new StringBuffer() ;
        sb.append("hello") ;
        sb.append("world") ;
        sb.append("javaee") ;
1、public StringBuffer replace(int start,int end,String str)
 使用指定的字符串str从指定位置开始到end-1处进行替换,返回该字符串缓冲区本身	
 		sb.replace(5,10,"高圆圆") ;
2、 public String substring(int start):从指定位置开始截取,默认截取到末尾,返回被截取后的字符串
		String str = sb.substring(5);
3、public String substring(int start,int end):从指定位置开始截取到指定位置end-1处,返回被截取后的字符串String
		String str = sb.substring(5,8);

获取字符串缓冲区的长度 ---int length()
获取字符串缓冲区的容量---int capacity()	

StringBuffer的特有功能:反转

StringBuffer的特有功能:
     public StringBuffer reverse() :字符串缓冲区反转功能,将字符串缓冲区中所有的字符序列反转!
    需求:
       键盘录入一个字符串,将字符串反转
     方式1:
        1)将录入的字符串---->转换成字符数组
        2)定义一个String s = "" ;
        3)将字符数组倒着遍历
        for(int i = 字符数组.length-1;i>0 ;i --){
           s += 字符数组[i] ;
        }
        4)返回结果变量s
 
public class StringBufferDemo3 {
    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;
        //提示并录入数据
        System.out.println("请输入一个字符串:" ) ;
        String line = sc.nextLine() ;                   
        //调用一个功能完成
        String result = reverse(line);
        System.out.println(result) ;
    }

    //方式2:使用StringBuffer的反转功能
    public static String reverse2(String s){
       StringBuffer sb = new StringBuffer() ;
       sb.append(s) ;
       return sb.reverse().toString() ;
        //return new StringBuffer(s).reverse().toString() ;
    }

    public static String reverse(String s){
        //定义一个空字符串
        String result = "" ;
        //将s字符串-->转换功能  --->字符数组
        char[] chs = s.toCharArray();
        for(int x = chs.length-1 ; x >= 0 ; x--){
            result += chs[x] ;
        }
        return  result ;
    }
}


反转应用案例:"To be or not to be" 反转为oT eb ro ton ot eb
public class Test3 {
    public static void main(String[] args) {
        String s = "To be or not to be" ;
        String result = reverseMyStr(s);
    }

private static String reverseMyStr(String s) {
		//根据空格分割字符串
        String[] strArray = s.split(" ") ;
        //创建一个字符串缓冲区
        StringBuffer sb  =new StringBuffer() ;
        StringBuffer buffer = null ;
        //遍历字符串数组
        for(int x = 0 ; x <strArray.length;x++ ){
            String ss = strArray[x] ;

            //创建一个新的字符串缓冲区区
            buffer = new StringBuffer(ss) ;  // Tobeornottobe
            //反转
            buffer.reverse() ;//otebrotonoteb
            buffer.append(" ") ;
            sb.append(buffer) ;  //

        }
        return sb.toString() ;
    }
}

StringBuffer和String的相互转换

一、String---->StringBuffer
     String s = "hello" ;
     StringBuffer sb = s ;

方式1)可以通过StringBuffer的有参构造方法
        //创建一个字符串缓冲
        StringBuffer sb = new StringBuffer(s) ;

方式2:通过StringBuffer的无参构造方法+append(String str)
        StringBuffer sb2  = new StringBuffer() ;
        sb2.append(s) ;

二、StringBuffer-->String
        //有一个字符串缓冲区--->里面存在字符序列
        StringBuffer buffer = new StringBuffer("100") ;
方式1) -->public String toString()
        String str = buffer.toString();
方式2)String类的构造方法
        String str2 = new String(buffer)  ;


相互转换练习
判断该字符串是否是对称字符串 
方式一:
public static boolean isSame2(String s){
        //利用StringBuffer的反转
        //如果将s--->转换StringBuffer---->反转----->转换成String---->和转换之前String可以equals(),就是对称的,否则不对称
        return  new StringBuffer(s).reverse().toString().equals(s) ;
    }

方式二:
    public static boolean isSame(String s){
        boolean flag = true ;
        //将字符串转换字符数组
        char[] chs = s.toCharArray();
        for(int x = 0 ; x < chs.length/2 ; x++){
            if(chs[x] !=chs[chs.length-1-x]){//两个字符比较 :比较ASCII码表的值是否相同
                    flag = false ;
                    break ;
            }
        }
        return flag ;
    }
}

StringBuffer和StringBuilder的区别

StringBuffer和StringBuilder的区别	
共同点:
	他们都支持可变的字符序列,都代表字符串缓冲区(存储的都是字符序列)(都是容器),底层都是会存在char[];
	他们作为方法形式参数,形式参数的改变都会影响实际参数
	他们具有相互兼容的API
不同点:
	StringBuffer是线程安全的类,执行效率低。他们几乎所有的成员方法都有一个关键字"synchronized"-->同步锁(悲观锁),能够解决线程安全问题
	StringBuilder是线程不安全的类,单线程程序(不考虑安全,只考虑执行效率)使用StringBuilder去替代StringBuffer,提高执行效率(相对StringBuffer,执行效率高)

String和int的相互转换

int--->String
1)使用字符串拼接符号  ""+任何类型数据= "新的字符串"
2)int--->Integer---->String
    int i = 100 ;
    Integer integer = new Integer(i) ;
    String str = integer.toString() ;
3)Integer的静态方法 public static String toString(int i)
	String str2 = Integer.toString(i) ;

String--->int
1)String---->Integer---->int
    String source = "10" ;
    Integer integer2 = new Integer(source) ;
    int value = integer2.intValue() ;
2)Integer提供的静态方法 public static int parseInt(String s)
	int value2 = Integer.parseInt(source);

面试题:StringBuffer和StringBuilder的区别?

1、这两个类都是字符串缓冲区,都支持可变的字符序列,(都有相同的功能)

2、StringBuffer:使用在多线程环境里面,能够保证线程安全---意味着同步---执行效率低

3、StringBuilder:是StringBuffer的简易替换,用于在单线程环境中,线程不安全---不同步---执行效率高

4、单线程使用StringBuilder:效率高(速度快)

基本数据类型对应的引用类型

jdk提供了一个类Integer类,提供了一些功能:十进制转换成对应的进制的方法(静态方法)
 
  四类八种的基本数据类型都会自动提升 对应的引用类型         jdk5以后新特性:自动拆装箱
  拆箱:这些包装类类型--->降为 基本类型
 装箱: 就是基本类型--->提升  对应的引用类型
              基本类型                       引用类型的默认值null
                  byte                        Byte
                  short                       Short
                  int                         Integer(特殊)
                  long                        Long
                  float                       Float
                  double                      Double
                  char                        Character(特殊)
                  boolean                     Boolean
这些四类八种中的基本数据类型可以String进行相互转换的---->中间桥梁 ---->对应的基本类型的包装类类型

//public static String toOctalString(int i) 以字符串形式体现八进制
//public static String toHexString(int i)  以字符串形式体现16进制
//public static String toBinaryString(int i)以字符串形式体现的2进制
        System.out.println(Integer.toBinaryString(100));
        System.out.println(Integer.toOctalString(100));
        System.out.println(Integer.toHexString(100));
//public static final int MAX_VALUE:常量:获取int的最大值
 //public static final int MIN_VALUE:常量:获取int的最小值
        System.out.println(Integer.MIN_VALUE) ;
        System.out.println(Integer.MAX_VALUE) ;

Integer

Integer类表示包含int类型的值
Integer类的构造方法:
1、public Integer(int value):创建一个Integer实例,里面包含的int类型的值
2、public Integer(String s) throws NumberFormatException: 将数字字符串转换成Integer的实例
   可能会出现数字格式化异常(字符串如果不是数字字符串,就会出现这个异常)

//创建一个Integer实例
//public Integer(int value):创建一个Integer实例,里面包含的int类型的值
        int a = 100 ;
        Integer i = new Integer(a) ;
        System.out.println(i) ;
// public Integer(String s) throws NumberFormatException:
//Integer i2 = new Integer("hello") ;//NumberFormatException:数字格式化异常
        Integer i2 = new Integer("50") ;
        System.out.println(i2);

Integer的自动拆装箱 
 //将100赋值给Integer类型的变量i
       Integer i  = 100 ;  //整数常量赋值Integer类型变量i   装箱
       i += 200 ;    //先拆箱,在装箱
       
		Integer i = Integer.valueOf(100);   //自动装箱 int--->Integer  //public static Integer valueOf(int i)
		i = Integer.valueOf(i.intValue() + 200);  //  i.intValue()--->public int intValue()--->将Integer-->int  //先自动拆箱,然后再通过valueOf(300)--->再装箱

int基本类型和引用String的相互转换

int基本类型和引用String的相互转换  (重点)
  String---int:      int  变量名 = Integer.parseInt(已知的数字字符串) 推荐
  int---->String:    Integer类提供静态方法   String 变量名 = Integer.toString(int类型的值)
int---->String
方式1:使用拼接符号
        int i = 100 ;
        String s = "" ;
        s += i ; //拼接符号 s = s+i
        System.out.println(s) ;//"100"
方式2:int---->Integer----->String
   //int-->Integer
        Integer integer = Integer.valueOf(i);
   //Integer--->String
        String str = integer.toString();
方式3:Integer---->String
   //public static String toString(int i)
        String str2 = Integer.toString(i);


String---->Integer---->int
一:一步执行
        //Integer类提供了静态方法
        //public static int parseInt(String s)throws NumberFormatException:要转的字符串必须为数字字符串
        //万能方法:String--->long  --->Long引用提供静态方法 public static long pasreLong(String str)
        String source = "1990" ;
        int value = Integer.parseInt(source);

二:分步执行: //Integer(String str)
        Integer ii = new Integer(source) ;
        //Integer--->int
        int value2 = ii.intValue();

Integer和int类型比较

Integer:将int类型赋值给Integer变量 这种格式,执行底层方式valueOf(int i)
 
    public static Integer valueOf(int i) {
       // 如果i的值在-128~127之间,直接从内部类--->IntegerCache缓存去中取数据
        if (i >= IntegerCache.low && i <= IntegerCache.high)
             return IntegerCache.cache[i + (-IntegerCache.low)]; //  cache属性:Integer cache[] 长度 =i+128
   return new Integer(i);   //如果上if不成立,重新开辟新的空间创建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 ;
        Integer i4 = new Integer(127) ;
        System.out.println(i3==i4) ;        //false   
        System.out.println(i3.equals(i4)) ;//true

        Integer i5 = 128 ; //new Integer(128) ;   不在-128~127范围, new Integer(128)
        Integer i6 = 128 ;//new Integer(128);
        System.out.println(i5==i6) ;  //false
        System.out.println(i5.equals(i6)) ;//true

        Integer i7 =  new Integer(128) ;
        Integer i8 =  new Integer(128) ;
        System.out.println(i7==i8) ; //false   两个对象
        System.out.println(i7.equals(i8)) ;//true  。Integer重写了equals方法

Character

 char类型的包装类类型:Character
  构造方法:
   		//public Character(char value):包含char类型的值
   		 Character ch = new Character((char)97) ;
成员方法:
   判断功能:
1、 public static boolean isDigit(char ch):判断当前这个字符是否为数字
		Character.isDigit('A')
2、 public static boolean isLowerCase(char ch):判断当前这个字符是否小写
		Character.isLowerCase('a')
3、 public static boolean isUpperCase(char ch):判断当前这个字符是否大写
        Character.isUpperCase('a')   
           

BigDecimal类

BigDecimal这个类是对小数可以进行精确计算的
构造方法:
      public BigDecimal(String val):将String类型数据构造成BigDecimal
          将double数据---使用"小数字符串"
成员方法:
1、 public BigDecimal add(BigDecimal augend):求和
		 BigDecimal bd1 = new BigDecimal("0.35") ;
         BigDecimal bd2 = new BigDecimal("0.35") ;
         System.out.println(bd1.add(bd2)) ;
2、public BigDecimal subtract(BigDecimal subtrahend):相减
		 BigDecimal bd3 = new BigDecimal("1.01") ;
         BigDecimal bd4 = new BigDecimal("0.036") ;
         System.out.println(bd3.subtract(bd4));
3、public BigDecimal multiply(BigDecimal multiplicand):乘法
   		 BigDecimal bd5 = new BigDecimal("0.35") ;
         BigDecimal bd6 = new BigDecimal("2.01") ;
         System.out.println(bd5.multiply(bd6));
4.1、public BigDecimal divide(BigDecimal divisor,int roundingMode):除法,第二个参数为舍入模式
     	 bd3.divide(bd4,BigDecimal.ROUND_HALF_UP);      
4.2、public BigDecimal divide(BigDecimal divisor,
                          int scale,//保留几位小数
                          int roundingMode)  //舍入模式  
         bd3.divide(bd4,1,BigDecimal.ROUND_HALF_UP);               
BigDecimal提供的模式  public static final int ROUND_HALF_UP:四舍五入

Random

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 r = new Random(1000) ;
        	Random r = new Random() ;
        	//产生10个随机数
        	for(int x = 0 ; x < 10 ; x ++){
        	int number = r.nextInt();  //产生是int类型的范围内随机数
        	int number = r.nextInt(50);   //产生0-50范围内随机数
       		 }
   		 }
	}

System类

java.lang.System:不能实例化:提供了静态字段(静态变量)
1、public static final PrintStream out :标准 打印输出流
	 	PrintStream ps = System.out ;
        ps.print(100) ;
2、public static final PrintStream err  标准错误输出流
 		PrintStream ps2 = System.err ;
        ps2.println("这是一个错误输出流打印数据,提示错误信息");
3、 public static final InputStream in  标准输入流
		InputStream is = System.in ;
        Scanner sc = new Scanner(is) ;

System类常用的成员方法:
1、public static long currentTimeMillis() 计算当前系统时间毫秒值  (很少单独用)
用来计算当前某个程序的时间复杂度(运行效率)
		long start = System.currentTimeMillis() ;
		long end = System.currentTimeMillis() ;
		System.out.println("共耗时:"+(end-start)+"毫秒");
2、public static void gc() 收到开启垃圾回收器   ---会调用finalize(),回收没有更多引用的对象
	    System.gc();
3、 public static void exit(int status): 
		System.exit(0) ;//参数为0,正常终止jvm
4、public static void arraycopy(  //数组拷贝
           Object src,  //原对象
           int srcPos,   //原对象中的某个位置
           Object dest,      //目标对象
           int destPos,       //目标对象的某个位置
           int length)      //指定的长度 
           )
           
       int[] arr = {11,22,33,44,55} ;
       int[] arr2 = {1,2,3,4,5,6,7,8} ;  
       System.arraycopy(arr,1,arr2,2,3);

Date类

 java.util.Date:表单特定的日期时间,还允许格式化和解析日期字符串
构造方法:
1、public Date():创建当前日期对象:获取当前系统日期时间
	 	Date date = new Date() ;
        System.out.println(date)  //格式:Thu Mar 16 14:07:46 CST 2023
2、public Date(long date):里面传入long类型的时间毫秒值,获取的表示从标准基准时间(称为“时代”)即1970年1月1日00:00:00 GMT起的指定毫秒数
		long time = 1000 ;
       	Date date = new Date(time) ;  //毫秒
成员方法:
1、 public long getTime():将Date对象转换成long类型时间毫秒值
2、public void setTime(long time):设置日期时间,参数时间毫秒值

Date和String日期文本相互转换

Date和String日期文本进行转换需要使用类DateFormat
DateFormat是日期/时间格式化子类的抽象类,它以语言无关的方式格式化和分析日期或时间
它具体的子类:SimpleDateFormat是一个具体的类,允许格式化(日期文本),解析(文本日期)

构造方法:
      public SimpleDateFormat(String pattern):参数是日期模式         "yyyy-MM-dd"
      pattern的组成:
              y:表示年份中某个值----->yyyy 表示年 "1996/2023/..."
              M:表示年中的月份------>MM     表示月:七月-->"07" 十月 -->"10"
              d:表示月中的日期值----->dd   表示 "01","11","31"..
成员方法:
 将Date---->String:格式化  public final String format(Date date)
 将String日期---->Date: public Date parse(String source)throws ParseException
 
案例:
public class DateDemo2 {
    public static void main(String[] args) throws ParseException {
        //当前系统日期对象
        Date date = new Date() ;
Date---->格式化---->String日期文本
//1)public SimpleDateFormat(String pattern):参数是日期文本模式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss") ;
//2)格式化:public final String format(Date date)
        String dataStr = sdf.format(date);
        System.out.println(dataStr) ;
String日期文本--->格式化---->Date
        String source = "2008-5-12" ;
//创建SimpleDataFormat
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd") ;
 //解析public Date parse(String source)throws ParseException
 //当SimpletDateFormat和给定日期文本格式不一致,就解析出错
        Date date2 = sdf2.parse(source);
        System.out.println(date2);
    }
}



相互转换练习案例
键盘录入出生年月日,计算来到这个世界多少天了?
 1)键盘录入String dateStr = "1990-02-27"
 2)将dateStr日期字符串---->java.util.Date
 3)获取当前那个Date日期时间 毫秒值  long getTime()
 4)System提供了一个方法获取当前系统时间毫秒值
 5)时间差值---然后换算成天

	public class DateTest {
    public static void main(String[] args) throws ParseException {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;
        //提示并录入数据
        System.out.println("请输入您的出生年月日:" ) ;
        String dateStr = sc.nextLine() ;//yyyy年MM月dd日/yyyy-MM-dd
        //将dateStr---->java.util.Date
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
        Date date = sdf.parse(dateStr);
        //获取当前date所在时间毫秒值
        long oldTime = date.getTime();
        //获取当前系统时间毫秒值
        long nowTime = System.currentTimeMillis() ;
        long time = nowTime - oldTime ;
        System.out.println("您来到这个时间有:"+(time/1000/60/60/24)+"天");
    }
}

Calendar类

java.util.Calendar:日历类(抽象类)
提供了获取年,年中的月,月中的日期,小时,小时分钟数,分钟中的秒数都可以获取到
如果有一个类是抽象类,可以直接new子类,或者是它提供了一些静态方法---->完成了一些事情,创建子类对象,返回值是当前抽象类的本身
 成员方法:
 1、public static Calendar getInstance() 创建日历对象
 2、public int get(int field):通过日历对象获取日历中的字段值
 参数:Calendar中提供的一些静态字段
 1、 public static final int YEAR:年份
 2、public static final int DAY_OF_MONTH/public static final int DATE:月中的日期
 3、 public static final int MONTH:月份
 4、 public abstract void add(int field,int amount):给指定的日历字段值添加或者减去时间偏移量


public class CalendarDemo {
    public static void main(String[] args) {
    //创建一个日历对象
    //Calendar c = new Calendar() ; //不能实例化:抽象类
     	 Calendar c = Calendar.getInstance(); //getInstance()--->创建Calendar类的子类对象

    //public int get(int field):通过日历对象获取日历中的字段值
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH) ;//默认计算0-11
        int date = c.get(Calendar.DAY_OF_MONTH) ;
        System.out.println(year+"-"+(month+1)+"-"+date);

 //public abstract void add(int field,int amount):给指定的日历字段值添加或者减去时间偏移量
//3年后的今天
       c.add(Calendar.YEAR,3) ;
        year = c.get(Calendar.YEAR) ;
        month = c.get(Calendar.MONTH) ;//默认计算0-11
        date = c.get(Calendar.DAY_OF_MONTH) ;
        System.out.println(year+"-"+(month+1)+"-"+date);*/

 //5年前的10天前
        c.add(Calendar.YEAR,-5);
        c.add(Calendar.DAY_OF_MONTH,-10);
        year = c.get(Calendar.YEAR) ;
        month = c.get(Calendar.MONTH) ;//默认计算0-11
        date = c.get(Calendar.DAY_OF_MONTH) ;
        System.out.println(year+"-"+(month+1)+"-"+date) ;
    }
}

集合和数组的区别

集合和数组区别?
1)长度区别
   	数组:固定
	集合:可变
2)存储数据类型的区别?
	数组:可以存储基本数据类型,也可以存储引用数据类型
	集合:只能存储引用类型   集合<泛型>
3)存储元素的区别?
	数组:数组存储的元素的数据类型必须一致
     集合:如果没有明确<泛型>,可以存储任意的引用类型(包含Object)

Collection

集合框架体系结构图:

在这里插入图片描述

Collection基本功能:

 Collection:单例集合顶层次的根接口,不能new,没有直接子实现类,是通过它子接口的子实现类来实例化
 泛型: 集合里面创建的时候,如果不带泛型可能程序安全问题;带了<>,模拟创建数组的时候,明确了数据类型
  <E>:element
  <T>:Type
  <K>:Key键
  <V>:Value值
 
Collection基本功能:
   添加元素:
         boolean add(E e):添加元素
    删除:
         boolean remove(Object o):删除指定的元素
         void clear():暴力删除:清空集合
    判断:
        boolean contains(Object o):是否包含指定的元素
   		boolean isEmpty():判断集合是否为空
   		
  Collection<String> c = new ArrayList<>() ;
   		c.add("hello") ;//添加元素
      	c.remove("hello")//删除元素
     	c.clear();//清空集合
     	boolean b = c.isEmpty();//判断集合是否为空
     	c.contains("hello")  //是否包含指定的元素,底层依赖Object 的equals方法,默认比较的地址值是否相等

普通for遍历集合

Collection集合高级功能:
	Object[] toArray():集合的传统方式遍历 将集合转换成对象数组
 //创建一个集合Collection
        Collection<Student> c = new ArrayList<>() ;
        //创建5个学生
        Student s1 = new Student("文章",35) ;
        Student s2 = new Student("王宝强",37) ;
        Student s3 = new Student("高圆圆",44) ;
        Student s4 = new Student("赵又廷",46) ;
        Student s5 = new Student("马伊琍",40) ;
        Student s6 = new Student("马伊琍",40) ;
        //添加功能
        c.add(s1) ;
        c.add(s2) ;
        c.add(s3) ;
        c.add(s4) ;
        c.add(s5) ;
        c.add(s6) ;
        //Object[] toArray()
        Object[] objects = c.toArray(); //objects--->存储5个学生
        for(int x = 0 ;x < objects.length ; x++){
            //System.out.println(objects[x]);//    objects[x] 类型Object--->每一个学生对象 new Student()
            //向下转型
            Student student = (Student) objects[x];
            System.out.println("学生的姓名是:"+student.getName()+",年龄是:"+student.getAge());

Iterator迭代器遍历集合

Iterator<E> iterator():Collection专有迭代器(遍历集合) (过渡)
  Iterator迭代器接口:
  方法:
  1、boolean hasNext(): 判断迭代器里面是否下一个可以遍历的元素
  2、 E next():获取迭代器的下一个元素 (和迭代器中的类型一致)
  开发中---集合遍历---->都用jdk5以后新特性:增强for循环 代替上面迭代器

        //使用Collection存储String字符串并进行遍历---使用Collection迭代器
        Collection<String> c = new ArrayList<>() ;
        //添加String
        c.add("android") ;
        c.add("JavaEE") ;
        c.add("mysql") ;
        c.add("hadoop") ;

        //获取Collection的迭代器
        //Iterator<E> iterator()
        Iterator<String> it = c.iterator();
        //E next() //E---类型需要和泛型的类型一致的

        //while循环 遍历
        while(it.hasNext()){
        	String s = it.next();
            System.out.println(s+"---"+s.length());  



迭代器实现原理:就是ArrayList集合的内部类实现Itr间接实现了两个功能
interface Iterator<E>{
    boolean hasNext() ;判断是否有下一个可以迭代的元素
    E next() ;获取下一个元素
}


interface Iterable<T>{
     Iterator<E> iterator();
}
interface Collection<E> extends Iterable  {
         Iterator<E> iterator();
}
interface List<E> extends Collection<E>{
        Iterator<E> iterator();
}
//具体的子实现类
public class ArrayList<E> implements List<E>{

        public Iterator<E> iterator() {
                return new Itr();
        }
        //私有的成员内部类Itr
        private class Itr implements Iterator<E> {
                boolean hasNext(){
                }
                Object next(){
                ...
               }
        }
}

增强for遍历集合

格式:
for(集合中存储的数据类型 变量名 : 集合对象){   //相当于迭代器,同样不能并发修改集合
         使用这个变量名即可;
   }
注意:要使用增强for遍历集合,集合对象不能null;   
	 防止空指针异常,在使用增强for之前,对集合进行非空判断

使用案例:
    	Collection<String> c = new ArrayList<>() ;
        c.add("hello") ;
        c.add("world") ;
        c.add("JavaEE") ;
        c.add("mysql") ;
 for(String s:c){//增强for替代迭代器  
            System.out.println(s);
        }

并发修改异常

ConcurrentModificationException:并发修改异常

什么叫并发:在某个时间点上同时进行
 在集合这块出现ConcurrentModificationException原因:
当使用迭代器去遍历元素的时候,同时不能使用集合对象去操作(修改或添加...)元素,就会出现这个异常。因为,迭代器在遍历元素的时候,集合添加一个新的元素,迭代器不知道
解决方案:
 1)集合遍历,集合添加  
 2)迭代器遍历,迭代器遍历
	 Collection没有直接操作----->子接口List特有功能(ListIterator:列表迭代器/List集合普通for+size()+get(int index))      

集合元素去重

Collection集合元素去重
新建空集合思想
	去遍历以前的集合,获取所有的元素。在新集合中判断,是否包含这个以前的元素,如果不包含,把这个元素添加新集合中

使用Collection<String>,使用ArrayList具体的子类,添加重复的String类型数据,保证元素唯一

public class Test2 {
    public static void main(String[] args) {
        //创建Collection
        Collection<String> c = new ArrayList<>() ;
        c.add("hello") ;
        c.add("hello") ;
        c.add("world") ;
        c.add("javaee") ;
        c.add("world") ;
        c.add("javaee") ;
        //新建一个空集合思想
        Collection<String> newColl = new ArrayList<>() ;
        //然后:去遍历以前的集合,获取所有的元素
        //在新集合中判断,是否包含这个以前的元素,如果不包含,把这个元素添加新集合中!
        for(String s :c){
            if(!newColl.contains(s)){//不包含。判断集合中是否包含此元素
               //ArrayList里面的contains底层依赖Object的equals方法,由于现在存String类型
               // String类型重写了Object的equals比较的是两个字符串内容是否相同,相同只存储一个
               //自定义子类使用contains()方法时,需重写equals和hashCode方法
                newColl.add(s) ;
            }
        }  

List集合常用三个子实现类

List集合常用三个子实现类特点:
    实际需求:单线程中,使用List完成一些事情,没有明确规定具体使用哪个实现类;默认使用ArrayList集合
1、默认:ArrayList
       底层数据结构是数组-->查询快,增删慢! (数组,通过整数索引查询)
       元素查找:  顺序查找,二分搜索(折半查找),哈希查找
       线程角度:
       线程不安全的类,是一个不同步,执行效率高
       底层扩容机制1.5倍
2、Vector
      底层数据结构是数组-->查询快,增删慢
      线程角度:
      线程安全的类,是同步的,执行效率低! 多线程环境下使用居多,单线程使用ArrayList代替Vector
3、LinkedList
      底层数据是链表, 查询慢,增删快
      线程角度:
      线程不安全的类,不同步的,执行效率高

List集合特点

List集合特点:
 元素有序(存储和取出一致),而且元素可以重复
Set集合:
 元素唯一的,无序(存储和取出不一致)
 
 List集合是Collection集合的子接口,它集合遍历方式:
	1)Collection的Object[] toArray()
    2)Collection的Iterator iterator() ;
    3)使用size()+ 存储的数据类型 get(int index)通过角标获取元素内容 :普通for循环格式
    4)ListIterator<E> listIterator()List集合的专有遍历方式 :列表迭代器
    5)增强for循环
    
        List<String> list = new ArrayList<>() ;
        list.add("hello") ;
        list.add("world") ;
        list.add("JavaEE") ;
        list.add("android") ;
        list.add("ios") ;

        //3)4)5)特有方式
        //使用size()+ 存储的数据类型 get(int index)通过角标获取元素内容 :普通for循环格式
        for(int x = 0 ; x < list.size() ; x++){
            //通过x角标值获取元素内容
            String s = list.get(x);
            System.out.println(s);
        }

        //ListIterator<E> listIterator()List集合的专有遍历方式 :列表迭代器
        ListIterator<String> lit = list.listIterator();//获取列表迭代器
        //ListIterator--->接口提供一些方法
        //boolean hasNext():判断是否有下个元素
        //E next():获取下一个元素
        while(lit.hasNext()){
            String s = lit.next();
            System.out.println(s);
        }

        //列表迭代器提供了一些功能,进行逆序遍历(前提必须有上面的正向遍历)
        //boolean hasPrevious():判断是有上一个元素
        //E previous():获取上一个元素
        while(lit.hasPrevious()){
            String previous = lit.previous();
            System.out.println(previous);
        }

        //增强for (推荐)
        for(String s:list){
            System.out.println(s) ;
        }
    }

List元素去重思想

在这里插入图片描述

使用List集合解决并发修改异常

使用List集合解决并发修改异常
  List有特有方式:
  	size()获取集合长度 结合  Object get(int index)通过索引值获取对应的内容
  特有添加元素的方式:
  	void add(int index,E element):在指定位置处,添加指定的元素
 List继承Collection--->Iterator是Collection的专有迭代器,没有提供添加功能,而
 List集合专有遍历方式ListIterator:列表迭代器
 
public class ListDemo {
    public static void main(String[] args) {

        //使用List集合存储String
        List<String> list = new ArrayList<>() ;

        list.add("hello") ;
        list.add("world") ;
        list.add("javaee") ;

// 1)集合遍历,集合添加
        //size()获取集合长度 结合  Object get(int index)通过索引值获取对应的内容
       /* for(int x = 0 ; x < list.size() ; x++){
            String s = list.get(x);
            //判断
            if("world".equals(s)){
                list.add("go") ; //add()方法继承自 Collection的方法
            }
        }*/


//2)迭代器遍历元素,迭代器添加元素
       // ListIterator<E> listIterator()
        //ListIteratr--->void add(E e)将指定的元素插入列表
        ListIterator<String> lit = list.listIterator();  //ListItr extends Itr  :都是ArrayList的内容类
        while(lit.hasNext()){
            //获取下一个元素
            String s = lit.next();
            //判断:如果s是"world",添加一个新的"go"
            if("world".equals(s)){
                  lit.add("go") ;
            }
        }

ArrayList

Arrays的toString的原码
public static String toString(int[] a) {  //实际参数 --->传入数组对象
        if (a == null)			//如果是是null
            return "null";			"null"
            
        int iMax = a.length - 1;  //最大索引值
        if (iMax == -1)				//如果最大索引值是-1
            return "[]";			"[]"

        StringBuilder b = new StringBuilder();   //单线程中使用StringBuilder
        b.append('[');						//追加"["
        for (int i = 0; ; i++) {			//遍历a数组
            b.append(a[i]);					//直接将所有数组的元素追加到字符串缓冲区中
            if (i == iMax)					//如果角标i取到最大索引值
                return b.append(']').toString();	//结束: 追加"]"--->转换成String
            b.append(", ");				//没有最大索引值,追加", "
        }
    }
ArrayList及增强for嵌套使用
需求:
三个Java班级:每一个班级看成ArrayList
三个班级组成一个大的集合ArrayList<ArrayList<Student>>,
 第一个班级存储
       高圆圆 22
       赵又廷 25
 第二个班级存储
       张三丰 50
       令狐冲 35
第三个班级存储
	    孙悟空 32
  		唐僧   40

public class ArrayListTest {
    public static void main(String[] args) {
        //先创建一个大的集合
        ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ;
        //第一个班级
        ArrayList<Student> firstArray = new ArrayList<>() ;
        Student s1 = new Student("高圆圆",22) ;
        Student s2 = new Student("赵又廷",25) ;
        firstArray.add(s1) ;
        firstArray.add(s2) ;
        //将firstArray添加到大集合中
        bigArray.add(firstArray) ;

        //第二个班级
        ArrayList<Student> secondArray = new ArrayList<>() ;
        Student s3 = new Student("张三丰",50) ;
        Student s4 = new Student("令狐冲",35) ;
        secondArray.add(s3) ;
        secondArray.add(s4) ;
        //将secondArray添加到大集合中
        bigArray.add(secondArray) ;

        //第二个班级
        ArrayList<Student> thirdArray = new ArrayList<>() ;
        Student s5 = new Student("孙悟空",32) ;
        Student s6 = new Student("唐僧",40) ;
        thirdArray.add(s5) ;
        thirdArray.add(s6) ;
        //将thirdArray添加到大集合中
        bigArray.add(thirdArray) ;


        //ArrayList<ArrayList<Student>>
        //遍历大集合
        System.out.println("学生信息是:\t");
        for(ArrayList<Student> array:bigArray){
            //每一个ArrayList集合里面存储的学生对象
            for(Student s: array){
                System.out.println(s.getName()+"\t"+s.getAge());
            }
        }
    }
}

ArrayList 和 选择排序思想 实现元素去重
使用List<String>,使用ArrayList具体的子类,
     添加重复的String类型数据,保证元素唯一(不能新建集合)
      1)接口多态:List接口指向  ArrayList 或者创建具体子实现类ArrayList<String>
      2)存储重复的String
      3)遍历List ,获取到每一个元素
      4)可以借助选择排序的思想:
      使用第一个角标对应的元素依次和后面的元素比较,将后面的元素删除,角标--
 
public class ArrayListTest {
    public static void main(String[] args) {
        //创建List:可以重复
        List<String> list  = new ArrayList<>() ;
        list.add("hello") ;
        list.add("hello") ;
        list.add("world") ;
        list.add("hello") ;
        list.add("javaee") ;
        list.add("javaee") ;
        list.add("android") ;
        list.add("android") ;
        list.add("ios") ;
        list.add("ios") ;
        //List集合:特有遍历方式 : size()获取集合长度    + list集合对象.get(角标)--->获取元素
        //选择排序的思想
        for(int x = 0 ; x < list.size()-1; x++){ //比较次数
            //获取到了所有元素
            //使用第一个角标对应的元素依次和后面的元素比较,将后面的元素删除,角标--
            for(int y = x +1 ; y < list.size() ; y ++){
                if(list.get(y).equals(list.get(x))){  //自定义类需重写equals和hashCode方法
                    //将后面的元素干掉
                    list.remove(y) ; //通过角标删除元素
                    y-- ;
                }
            }
        }
        //遍历集合
        for(String s:list){
            System.out.println(s);
        }
    }
}
ArrayList_Login_Register 登录注册功能实现
接口实现:
 
public class UserDaoImpl implements UserDao {
    //静态实例
    private static List<User> list = new ArrayList<>() ;
    //登录和注册的时候,需要使用同一个集合,这个集合被共用
   /* static{
        List<User> list  = new ArrayList<>() ;
    }*/

    /**
     * 这个功能,用户登录功能
     * @param username  键盘录入 用户名
     * @param password  键盘录入的密码
     * @return  返回true,登录成功;否则,登录失败
     */
    @Override
    public boolean isLogin(String username, String password) {
        System.out.println(list); //测试
        //假设思想
        boolean flag = false ;//false:不成功
        //遍历List集合,取数据
        //增强for
        if(list!=null){ //防止空指针异常
            for(User u :list){
                //判断如果当前键盘录入的username和集合中的包含的用户的用户名一致,
                // 同时 键盘录入的密码和集合中包含的用户的密码一致,return true
                if(username.equals(u.getUsername()) && password.equals(u.getPassword())){
                    flag = true ;
                    break ;
                }
            }
        }
        return flag ;
    }

    /**
     * 这个功能是用户注册功能
     * @param user 需要注册的用户
     */
    @Override
    public void register(User user) {
        //创建一个List集合,存储用户
       // List<User> list = new ArrayList<>() ;

        list.add(user) ;
    }

  /*  @Override
    public List<User> findAll() {
        for(User user:list){
            System.out.println(user);
        }
        return list;
    }*/
}

测试类:
    while(true){
            //给出一些选项
            System.out.println("-----------------------欢迎访问xxx用户管理系统--------------------------") ;
            System.out.println("1,登录 2,注册, 3,退出");

            //创建键盘录入对象
            Scanner sc = new Scanner(System.in) ;
            System.out.println("请输入您的选择器:") ;
            String choiceNum = sc.nextLine() ;

            //接口多态:
            UserDao ud = new UserDaoImpl() ; //使用注册和登录功能
            switch (choiceNum){
                case "1":
                    System.out.println("-----------------欢迎进入登录界面-------------------------");
                    //输入登录的用户名和密码
                    System.out.println("请您输入登录的用户名:") ;
                    String username = sc.nextLine() ;

                    System.out.println("请您输入登录的密码:") ;
                    String password = sc.nextLine() ;

                    //调用登录功能
                    boolean flag = ud.isLogin(username, password);
                    if(flag){
                        System.out.println("恭喜您,登录成功!") ;
                        System.out.println("进入后台管理系统") ;
                        System.exit(0) ;
                    }else{
                        System.out.println("对不起,用户名或者密码输入错误!");
                    }
                    break ;
                case "2" :
                    System.out.println("-----------------欢迎进入注册界面-------------------------");
                    //录入用户名和密码,调用用户的注册功能
                    System.out.println("请输入用户名:") ;
                    String name = sc.nextLine() ;

                    System.out.println("请输入密码:") ;
                    String pwd = sc.nextLine() ;

                    //封装用户数据
                    User user = new User() ;
                    user.setUsername(name) ;
                    user.setPassword(pwd) ;

                    //调用注册功能
                    ud.register(user) ;
                    System.out.println("恭喜您,注册成功!");
                    break ;
                case "3":
                default:
                    System.out.println("谢谢使用,欢迎下次再来,再见!");
                    //break ;
                    System.exit(0) ; //终止jvm了
            }
        }

LinkedList

LinkedList特有方法
LinkedList的特有方法:
    public void addFirst(E e) :在链表开头插入元素
    public void addLast(E e) :在链表末尾插入元素
    public E removeFirst(): 删除链表开头的第一个元素并返回该元素
    public E removeLast()从此列表中删除并返回最后一个元素。
    public E getFirst():返回链表头元素
    public E getLast():返回链表链尾元素

public class LinkedListDemo {
    public static void main(String[] args) {
        //创建LinkedList集合
        LinkedList<String> link = new LinkedList<>() ;

        //添加元素
        link.addFirst("hello") ;
        link.addFirst("world") ;
        link.addFirst("javaee") ;

        //删除
        System.out.println(link.removeFirst()) ;
        System.out.println(link);

        //获取
        System.out.println(link.getFirst());
        System.out.println(link.getLast());
    }
}

LinkedList集合应用场景
在这里插入图片描述

Vector

Vector:底层数组,查询快,增删慢,线程安全的,执行效率低!
 Vector集合的特有功能:
	 1、 遍历方式:Collection的Object[] toArray()
     2、 Collection的Iterator iterator()
     3、List接口提供的 size()+get(int index)
     4、 List接口提供的ListIterator listiterator()
     5、特有遍历方式
         public Enumeration<E> elements()--->相当于集合的迭代器
                Enumeration接口:枚举组件
                boolean hasMoreElements()---->相当于boolean hasNext()
                 E nextElement()          ---->相当于E next()

               public E elementAt(int index)--->相当于List的get(int index)+size方法相结合

      6、增强for
 添加:
      public void addElement(E obj)--->相当于List的add()
      public E elementAt(int index)--->相当于List的get(int index)
 

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

        //创建Vector集合
        Vector<String> v = new Vector<>() ;

        //public void addElement(E obj)--->相当于List的add()
        v.addElement("hello");
        v.addElement("world");
        v.addElement("javaee");
        v.addElement("mysql");

// 遍历方式1:
        //public E elementAt(int index)--->相当于List的get(int index)+size方法相结合
        for(int x = 0 ; x < v.size() ; x++){
            String s = v.elementAt(x);
            System.out.println(s);
        }
// 遍历方式2:
       		 //public Enumeration<E> elements()--->相当于集合的迭代器
             //Enumeration接口:枚举组件
             //boolean hasMoreElements()---->相当于boolean hasNext()
             //E nextElement()          ---->相当于E next()
      /*  for(Enumeration<String> en = v.elements(); en.hasMoreElements();){
            System.out.println(en.nextElement());
        }*/
        Enumeration<String> en = v.elements() ;
        while(en.hasMoreElements()){
            String s = en.nextElement();
            System.out.println(s);
        }
// 遍历方式3:
        for(String s:v){
            System.out.println(s);
        }

Set接口

 Set接口特点:
 无序(存储和取出不一致),不能保证迭代次序,但是可以唯一
实现子类: HashSet<E> : 存储和取出,保证元素唯一。自定义类型必须重写HashCode和equals方法,保证自定义类的对象唯一
            ---底层是HashMap实例(哈希表)
实现子类: TreeSet<E> : 存储和取出,同时需要进行排序的取出
            ---底层是依赖TreeMap实例(红黑树结构)
 HashSet<String> hs = new HashSet<>() ;
        hs.add("hello") ;
        hs.add("hello") ;
        hs.add("hello") ;
        hs.add("world") ;
        hs.add("world") ;
        hs.add("world") ;
        //遍历
        for(String s:hs){
            System.out.println(s);
        }

HashSet

使用HashSet存储一些学生(姓名,年龄),让你保证学生对象唯一
自定义类型必须重写HashCode和equals方法,保证自定义类的对象唯一
 HashSet<Student> hs = new HashSet<>() ;
        //创建学生对象
        Student s1 = new Student("高圆圆",44) ;
        Student s2 = new Student("高圆圆",44) ;
        Student s3 = new Student("高圆圆",35) ;
        Student s4 = new Student("文章",35) ;
        Student s5 = new Student("文章",35) ;
        hs.add(s1) ;
        hs.add(s2) ;
        hs.add(s3) ;
        hs.add(s4) ;
        hs.add(s5) ;
        for(Student s:hs){
            System.out.println(s.getName()+"---"+s.getAge());
        }
HashSet集合的add方法源码
public class HashSet<E>  implements Set<E>{

        //transient:io流 :map属性不参与序列化(io流相关的)
        private transient HashMap<E,Object> map;
          private static final Object PRESENT = new Object();

            public HashSet() {
                //创建了一个HashMap集合
                map = new HashMap<>();
            }

            public boolean add(E e) { //"添加的那些元素"
                    //map集合的添加方法put(k,v)
                    //e:那些元素,
                    return map.put(e, PRESENT)==null;
                }

}

//HashMap集合
class HashMap<K,V> implements Map<K,V>{

        public V put(K key, V value) { //key:传过来的元素,v是常量
                return putVal(hash(key), key, value, false, true);
            }

         //1)"hello","hello","hello","world"...
         static final int hash(Object key) {  //将key那些元素传进来
                     int h;  //初始化h
                     return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
          }

         //2)执行putVal()

         //jdk8以后:数组+链表+红黑树结构
         final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                            boolean evict) {
                 Node<K,V>[] tab; Node<K,V> p; int n, i;
                 if ((tab = table) == null || (n = tab.length) == 0)
                     n = (tab = resize()).length;
                 if ((p = tab[i = (n - 1) & hash]) == null)
                     tab[i] = newNode(hash, key, value, null);
                 else {
                     Node<K,V> e; K k;
                     if (p.hash == hash &&
                         ((k = p.key) == key || (key != null && key.equals(k))))
                         e = p;
                     else if (p instanceof TreeNode)
                         e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
                     else {
                         for (int binCount = 0; ; ++binCount) {
                             if ((e = p.next) == null) {
                                 p.next = newNode(hash, key, value, null);
                                 //当链表结构取到7的时候,开始进行"树化"操作
                                 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                     treeifyBin(tab, hash);
                                 break;
                             }
                             if (e.hash == hash &&
                                 ((k = e.key) == key || (key != null && key.equals(k))))
                                 break;
                             p = e;
                         }
                     }
                     if (e != null) { // existing mapping for key
                         V oldValue = e.value;
                         if (!onlyIfAbsent || oldValue == null)
                             e.value = value;
                         afterNodeAccess(e);
                         return oldValue;
                     }
                 }
                 ++modCount;
                 if (++size > threshold)
                     resize();
                 afterNodeInsertion(evict);
                 return null;
             }
}

HashSet集合依赖于HashMap---->间接与hash()---->依赖于hashCode(),put()方法--->equals方法
存储String类型,字符串重写过来equals和hashCode(),元素唯一!

TreeSet

TreeSet<E>有两种排序方式:
 		自然排序:public TreeSet():使用自然排序,当前里面存储的类型必须实现Comparable
 		比较器排序:
 		
     TreeSet<String> ts = new TreeSet<>() ; //使用TreeSet的无参构造方法,默认使用自然排序
        ts.add("world") ;
        ts.add("java") ;
        ts.add("abc") ;
        ts.add("bcd") ;
        ts.add("defg") ;
        ts.add("defg") ;
        ts.add("wyz") ;

        for(String s:ts){
            System.out.println(s);
        }

在这里插入图片描述

TreeSet自然排序
自然排序:TreeSet<E>() 无参构造方法
使用自然排序,当前里面存储的类型必须实现Comparable,重写compareTo方法

 TreeSet<Student> ts = new TreeSet<>() ; //无参构造方法
        Student s1 = new Student("gaoyuanyuan",35) ;
        Student s2 = new Student("gaoyuanyuan",35) ;
        Student s3 = new Student("gaoyuanyuan",25) ;
        Student s4 = new Student("wenzhang",38) ;
        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
   for(Student s:ts){
            System.out.println(s.getName()+"---"+s.getAge());
        }
        
 public class Student  implements Comparable<Student>{//实现接口Compareable    
  //重写compareTo方法
    @Override
    public int compareTo(Student s) { //存储到每一个学生对象
        //主要排序条件:
        // 需要按照学生的年龄从小到大排序
        int num = this.age - s.age ;
        //int num = s.age - this.age ;
        //年龄相同,比较姓名的内容是否相同
        int num2 =(num==0)?(this.name.compareTo(s.name)):num ;
        return num2;
    }
TreeSet的add方法源码
class TreeSet<E> implemnts Set{

        private transient NavigableMap<E,Object> m;

         public boolean add(E e) {
                return m.put(e, PRESENT)==null;
          }

}

class TreeMap<K,V> implements NavigableMap<K,V>{


public V put(K key, V value) { //K key---->s1---s8学生对象 类型Student
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths //比较器排序/自然排序
        Comparator<? super K> cpr = comparator;  //比较器排序
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException(); //元素null,空指针异常
            @SuppressWarnings("unchecked") //压制警告

                //将key的类型
                <?>:任意Java类型
                <? extends E> 向下限定  E这个类型或者它的子类
                <? super E>:向上限定 E这个类型或者它的父类

                //K--->Student类型--->
                Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;  //左子节点
                else if (cmp > 0) //右子节点
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }
}

要进行自然排序,TreeSet存储类型必须实现接口Compareable接口,重写compareTo方法,否则报错

List和和Set集合的区别

1)是否有序
	List存储和取出一致,有序的
	Set存储和取出不一致,不能保证迭代次序---->默认使用HashSet--->HashMap集合
2)是否重复
	List可以允许元素重复
	Set集合中存储的元素唯一
3)具体实现类的数据结构不同
	List集合--->ArrayList/Vector:底层数据结构:数组
			   LinkedList底层数据结构:链表
	Set集合---->HashSet基于HashMap实例(底层哈希表)
				TreeSet基于TreeMap的实例(底层是一种红黑树(自平衡的二叉树)结构)

TreeSet集合存储自定义类型如何实现自然排序

TreeSet集合要实现自然排序,使用无参构造方法,而且需要保证TreeSet存储的类型必须实现Compareable接口中的compareTo方法(T t)

大部分常用了String,Character,Integer..等等都会实现Compareable接口,完成自然升序排序
class Student implements Compareable<Student>{
       //属性私有化
    //setXXX(xx)/getXXX()
    public int compareTo(Student s){
        //需要按照主要条件排序
        //自己分析次要条件
        return 结果;
    }
}

HashSet集合存储自定义类型,如何保证元素唯一

HashSet集合保证自定义类型的元素唯一:
		add方法--->依赖于HashMap的put方法---->putVal()方法
		--->间接依赖于Object的hashCode()和equals方法;
		当前自定义类型必须重写Object的equals和hashCode,保证元素唯一

`

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值