Java基础知识总结(四)

常用类

重要的几个类

java.lang.Object类

表示所有的类的根类(超类或者父类),所有的类默认继承Object,拥有这个类的所有私有方法

public final class getclass():获取任何Java类型的字节码文件对象(返回值表示正在运行的那个类)

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

三种方式

​ public final Class getClass() 任意java对象调用getclass()

​ 任意java类型的class属性

​ class类有一个静态方法forName(“包名.类名”)

int hashcode() 哈希码值(理解为"地址值",并非实际地址值)

public int hashcode() 获取对象的哈希码值

hashcode()(哈希算法 hash table);理解为地址值,不是真是地址值,每一个对象的hash值不同

String toString(): 重点

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

几乎java所有类都会重写toString()方法

boolean equals(Object obj):比较两个数据(引用类型)是否相等

指定其他对象于此对象是否"相等"

==和equals()方法区别?

==:比较两个基本类型,数据值是否相等

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

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

重写equals:比较每一个对象的成员信息是否相同,如果一样,还要比较每一个成员信息hashCode()哈希码值是否一样,如果相同系统认为这两个人是一样的!

clone():克隆

要进行创建对象的副本,前提这个类必须实现clonable接口,否则无法克隆

jdk提供的接口,什么都没有(方法都没有),这种接口称为"标记接口"

Cloneable接口就是标记哪些类能进行clone

protected Object clone() throws CloneNotSupportedException 创建对象并返回它的"副本"

方法本身就会带有CloneNotSupportedException:克隆不支持的异常(当要对某个Object的类进行克隆,如果这个类不能实现cloneable接口,那么就会出现这个异常)

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,再录入Sstring-----nextLine(),这块会出现被漏掉(“回车符号”)

解决方案:

1)在录入第一个int之后,重新创建一个新的键盘录入对象Scanner,然后在使用nextLine()

2)在录入String----String next()

String以及StringBuffer(字符串缓冲区)(重点)

String类:这个类是被final修饰的不能被继承

字符串是不变的;他们的值在创建后不能被更改(字符串是一个常量,存储在常量池中)

构造方法:

public String():空字符串 类似于String s = “”;

public String(Sring original):构造一个字符串对象,里面指定一个字符串常量值

public String(byte[] bytes):使用平台默认字符集(idea默认uft-8)解析解码---->字节数组—>字符串

String(byte[] bytes,int offset,int length):将一部分字节数组构造成字符串

public String(char[] value):将字符数组—构造成String

public String(char[] value,int offset, 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) :将一部分字节数组构造成字符串

面试题

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

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

字符串有length(),

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

String类相关的获取功能:

1)public char charAt(int index):获取指定索引处的字符

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

3)public String concat(String str):拼接功能—将一个字符串拼接到指定字符串的后面(末尾追加)

4)public String substring(int beginlndex):截取–>从指定位置开始截取到末尾结束!

public String substring(int beginIndex, int endIndex) 截取—>从指定位置开始截取到指定位置结束

5)public String[] split(String regex):拆分(分割),按照指定的分割符将字符串拆分成字符串数组

6)public int indexOf(int ch):返回此字符第一次在字符串出现的索引值

​ public int lastlndexOf(int ch) : 返回此字符最后一次在字符中出现的索引值

//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类的转换功能

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)

编码和解码必须一致,否则乱码!

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 s = new String(“hello”) ;

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

区别:

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

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

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+"----");
      

字典顺序比较面试题

按照字典顺序比较,它的结果是多少? 考察的就是compareTo的源码

public int compareTo(String anotherString):两个字符串按照字典顺序比较!
*

两个字符串进行字典顺序比较,先算出长度,取出最小值,然后比较每一个字符,如果这俩个字符串的第一个字符都不相同

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

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

 String s1 = "hello";
 String s2 = "hel" ;
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));
}

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

StringBuffer:线程安全的类,支持可变字符序列!

线程----->依赖于进程,线程执行的最先单元!

线程安全—>意味着 “同步”----->执行效率低

举例:银行的网站/医院平台

线程不安全---->“不同步”----->执行效率高

举例 论坛网站

构造方法:

public StringBuffer()----->空参构造,初始容量16个字符

public StringBuffer(int capacity)—>指定容量大小的字符串缓冲区(很少用)

public StringBuffer(String str)---->将指定的字符串内容构造到字符串缓冲区中,容量=当前str的长度+16

int length(获取字符缓冲区长度)

int capacity() 获取容量大小

 // 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类型)在指定位置处插入指定的数据,返回字符串缓冲区本身

StringBuffer的获取功能

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 ;

   }
   }

面试题

 * 在实际开发中,牵扯很多类型之间的相互转换

 *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);


    }

}

String和StringBuffer/StringBuilder的区别?

String:是一个常量,一旦被赋值,其值不能被更改 ,不可变的字符序列!

作为形式参数,形式参数的改变不影响实际参数(和基本类型作为形式参数传递的效果一致 ,特殊的引用类型)

StringBuffer:支持可变的字符串序列,线程安全的类--->同步的--->执行效率低

StringBuffer的大部分功能--->synchronzied:同步锁(悲观锁)(多线程去讲)

作为形式参数,形式参数的改变直接影响实际参数

StringBuilder:StringBuffer具备相互兼容的API,线程不安全的类---不同步的---->执行效率高

单线程程序(只考虑效率),使用StringBuilder去替代StringBuffer

多线程环境下(要考虑安全),使用StringBuffer
 *
 */
public class StringBufferTest {
public static void main(String[] args) {
    String s = "helloworld" ;//推荐创建字符串的格式
    System.out.println(s) ;
    change(s) ;
    System.out.println(s) ;//helloworld
    StringBuffer sb = new StringBuffer("helloworld") ;
    System.out.println(sb) ;
    change(sb) ;
    System.out.println(sb) ;//helloworldjavaee
}
public static void change(StringBuffer sb){//字符串缓冲区类型
    sb.append("javaee") ;
    System.out.println(sb) ;
}
public static void change(String s) {//字符串类型
    s += "javaee";
    System.out.println(s) ;//helloworldjavaee
}
}

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

Date日期格式------->String日期文本

String日期文本 2022/11/15 2022年11月15日

​ 2022/11/15 2022年11月15日------->Date(重点)----->解析

应用场景:用户注册 填写 出生日期  "1995-05-27"   String---->数据库Date格式
    *

 格式化或者解析:使用DateFormat,它是一个抽象类,不能实例化,用的抽象类的子类SimpleDateFormat
   

 Date日期--->String格式化

 public final String format(Date date)

 构造方法

 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"

  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ") ;//解析出问题了!
    
   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)+"天");
           }
          }
    

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+"日") ;
    

Integer类:包装的int类型的值

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

byte Byte

short Short

int Integer

long Long

float Float

double Double

char Character

boolean Boolean

基本类型 引用类型 String

String Integer int

控制台打印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));
}
}

自定义一个工具类:—构造私有化,外界不能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) ;
}
}

JDK5的其他新特性

1)静态导入------导入到方法级别

前提使用静态导入,这个类的方法必须为静态

在使用静态导入的时候,导入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 ;

}
}

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---->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(小数字符串)

}

}

构造方法

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);
 /*   public static boolean isDigit(char ch):判断是否为数字字符
    public static boolean isUpperCase(char ch):判断是否为大写字母字符
     public static boolean isLowerCase(char ch):判断是否为小写字母字符*/
    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'));

}
}

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类产生随机数
       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);
       }
   }
   }

例题

需求:键盘录入一个字符串,统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
*

分析:

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+"个");

}
}

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));
}
}
/*
*

面试题:

final,finalize,finally有什么区别?

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

修饰类,类不能被继承

修饰符成员方法,方法不能被重写

修饰变量,此时常量

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

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

//可能出现问题的代码

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

//处理异常

}finally{

//释放系统资源(Java底层语言都是c)

//Io流(创建文件/流对象都需要关闭) /jdbc(连接对象,执行对象,查询对象都需要close)

}

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(Bigecimal divisor):除

public BigDecimal divide(BigDecimal divisor,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)); //支持四舍五入
       
       }
       }
    

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

1)长度区别

​ 数组长度固定

​ 集合长度是可变的

2)存储数据类型的区别

​ 数组:皆可以存储基本类型,也可以存储引用类型数据,但是这些数据的类型必须一致!

​ 举例: int[] arr =new int[3];

​ student[] Students=new Student[5];

​ 集合:只能存储引用类型数据,

集合Colleciton

没有jdk提供直接实现的,通过具体的子接口list/Set的子实现类实现

创建集合的时候:里面存储的引用类型的元素

模拟数组,创建集合的时候就明确了集合中存储的数据类型,否则导致程序不安全!

常用基本功能:

添加: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[] toArry() 不推荐,还是变成数组!

  •  * //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());}
    
       }
    
    }
    

2)Collection的专用遍历方式:迭代器

Iteratoriterator()

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

例题

* ```java
   * 使用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);
  ​    }
  
  
  
  }
  
  }
  ```

List集合的特点

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

List集合的特有功能:

​ void add(int index,E element):在指定位置前面加入新的元素

​ E get(int index):获取指定位置处的元素

​ E set(int index, E element):在指定位置处替换(修改)新的元素

​ ListIterator lisrIterator():List集合的专有遍历----->列表迭代器

​ ListIterator------>正向列表遍历:Boolean hasNext()+E next():获取下一个元素

​ 反向列表遍历:Boolean hasPrevious()+E pervious:获取上一个元素(必须有正向遍历列表)

  •  * 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去重

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

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()----->依赖于Objectequals()方法
 *String类型 人家已经重写了Obejctequals()方法
 * 比较的字符串内容是否相同
    */
 

第二种方式

* ```java
   * 使用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);
     }
     
     }
     }
  ```

面试题

* ```java
   * 用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(),成员信息是否一样,如果一样,还要比较成员的哈希码值是否一样
     
   * 都相同,就是同一个人
     */
  ```

使用ArrayList模拟等陆注册

Vector和LinkedList的特有功能

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

特有的功能:

  public void addElement(E obj):将指定元素添加到Vector集合中(默认追加)
   
public Enumeration<E> elements():获取枚举组件接口----->类似于Collection集合的Iterator  iterator();

Enumeration接口

Boolean hasMoreElements()判断是否有更多的元素---->类似于Iterator里面的boolean hsaNext()

E nextElement():获取下一个元素--------->类似于Iterator里面的E next()

public E elementAt(int index):通过索引值获取元素—>类似于List集合的E get(int index)

int size():获取集合元素数

* ```java
   * 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);
     }
     }
     }
  ```

LinkedList集合:

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

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

特有功能:

添加元素

public void addFirst(E e)将指定的元素加到列表的开头

public void addLast(E e)将指定的元素加到链表的末尾

public E getFirs():获取第一个元素

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集合:唯一/无序(不能保证迭代顺序)

Set集合:元素唯一的 默认情况使用HashSet进行实例

HashSet----哈希表—依赖于HashMap

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 (自然排序/比较器排序:依赖于使用的构造方法)

TreeSet集合

TreeSet集合—>Set集合的实现类,它应该满足保证元素唯一

底层基于TreeMap<K,V>,它是一个红黑树(red-black-tree)

有自然排序/比较排序

构造方法:

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

现在使用TreeSet存储Integer类型的元素

结论:

要实现自然排序,name使用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);
}

}
}

Map<K,V>键值对元素,遍历方式

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

Map和Collection的区别 ??


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

Collection集合的应用范围大:

ArrayList

Vector

LinkedList

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

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

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

应用范围:

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):比较器排序
*

如果键是自定义类型,键必须唯一,而且需要有排序规则!
*

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

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<T> list):针对List集合按照自然顺序排序

public static <T extends Comparable<? super T>> void sort(List<T> list,Comparator<T> com):

针对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());
}

多线程

线程和进程的概念

线程依赖于进程存在!

进程:能够调用系统资源的独立单位!

多线程:计算机都是支持多进程的,提高CPU的使用率!

​ 开启多个进程的时候,玩游戏的同时可以听音乐,他们并不是同时进行的,而是一点时间片在两个进程之间进行高效切换!

线程: 能够执行的最小单位!(一个线程可以看成进程的某个任务)

jvm是多线程?

是一个多线程,至少是两个线程

main线程-----用户线程

gc-----------垃圾回收器 开启垃圾回收线程(回收没有的对象)

多线程的意义:多个线程在互相抢占CPU的执行权! 线程的执行具有随机性!

java创建多线程

两种方式:

​ 1)继承关系: java提供的Thread

​ ⑴自定义一个类,继承自Thread类

​ ⑵重写Thread类的run方法---->完成一些耗时的操作

​ ⑶在main用户线程中,创建当前这个类的对象

​ ⑷开启线程---->不是run方法,run方法只是一个普通方法(仅仅执行线程里面的内容:读文件/完成io的操作…)

​ 启动线程start()-----jvm是调用run线程的方法,结果是两个线程互相抢占(具有随机性)

启动线程,想知道哪一个线程执行数据---Thread类提供一些基本功能:

public final void setName(String name):设置线程的名称

public final String getName():获取线程名称
 *
 *
 */
public class ThreadDemo {
public static void main(String[] args) {

//在main用户线程中,创建当前这个类对象
MyThread mt = new MyThread() ;
MyThread mt2 = new MyThread() ;//第二个线程
//开启线程

   // mt.run();
   // mt.run();

//执行线程之前,设置线程名称
mt.setName("线程1") ;
mt2.setName("线程2") ;

​    mt.start();//mt.start();//java.lang.IllegalThreadStateException 非法线程状态异常(一个线程不能启动多次)
​    mt2.start();

}

}

​ 2)实现关系: Runnable接口(方式2:使用java设计模式之静态代理—设计模式之结构设计模型的一种代理类/和被代理类都需要实现统统一个接口)

面试题

java能够直接创建多线程吗?

java是不能直接操作系统资源的,底层c语言是可以操作系统的

面试题:线程有几种状态

Thread类里面的内部枚举类

NEW 新建

RUNNABLE 运行

BLOCKED 阻塞

WAITING

TIMED_WAITING

TERMINATED

线程的生命周期

线程的调度相关的方法

线程的优先级:

优先级越大,线程抢占CPU执行权的几率越大!

public static final int MAX_PRIORITY 10 最大优先级

public static final int MIN_PRIORITY 1 最小优先级

public static final int NORM_PRIORITY 5 默认优先级

给线程设置优先级

public final void setPriority(int newPriority)

获取线程的优先级

public final int getPriority()
 */
public class ThreaDemo2 {
public static void main(String[] args) {
    //创建三个线程对象
    PriorityThread pt1 = new PriorityThread() ;
    PriorityThread pt2 = new PriorityThread() ;
    PriorityThread pt3 = new PriorityThread() ;

pt1.setName("李渊") ;
pt2.setName("李世民") ;
pt3.setName("李元霸") ;
//System.out.println(pt1.getPriority()+"---"+pt2.getPriority()+"---"+pt3.getPriority());
//启动之前,设置优先级
pt1.setPriority(10) ;
pt3.setPriority(1) ;

//启动线程
pt1.start() ;
pt2.start() ;
pt3.start() ;

}
}
线程的join()

public final void join() throws InterruptedException 等待该线程终止

线程1,线程2,线程3,线程2在线程1的后面执行,线程3在线程2的后面执行---使用join()方法
*
 */
public class JoinThreadDemo {
public static void main(String[] args) {
    //创建三个线程
    JoinThread jt1  = new JoinThread() ;
    JoinThread jt2  = new JoinThread() ;
    JoinThread jt3  = new JoinThread() ;
    //设置线程名称
    jt1.setName("高圆圆") ;
    jt2.setName("刘亦菲") ;
    jt3.setName("张佳宁") ;//启动线程
​    jt1.start();//public final void join() throws InterruptedException 等待该线程终止try {
​        jt1.join();//可能出现的代码   第一个线程等待该线程终止} catch (InterruptedException e) {
​        e.printStackTrace();  //处理异常: printStackTrace() 打印跟踪}

​    jt2.start();
​    jt3.start();
}

}
线程的yield()

public static void yield():暂停当前正在执行的线程,执行其他线程

写在线程类里

public class YieldThread  extends  Thread{

//线程1,线程2
@Override
public void run() {
    //线程1-->0
    for(int x = 0 ;x <200; x++){
        System.out.println(getName()+":"+x) ;
        Thread.yield();
    }
}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值