20221114-20221118周总结

20221114

常用类Object(重点)

String to String

返回对象的字符串表示形式,结果应该是一个更容易让人读懂的信息表达式(建议所有的子类都覆盖这个方法)
几乎Java所有类都会重写toString()方法
== idea—>alt+ins---->toString==
2)
hashCode()(哈希算法 hash table)“理解为地址值”,不是真实地址值,每一个对象的hash码值不同

==和equals()方法区别?

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

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

  • 而Object的equals方法,默认比较的是两个引用类型的地址值是否相等,建议子类需要重写这个equals(),重写之后比较的是
  • 两个对象的成员信息是否相同!(Java中所有类都会重写!) ,重写equals方法,必须同时重写hashCode()方法
  • 重写equals:比较每一个对象的成员信息是否相同 如果一样,还要比较每一个成员信息 hashCode()哈希码值是否一样,如果都相同
    系统认为这个两个人是一样的!

alt+ins—>equals and hashcode方法

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

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

Object的克隆方法

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

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

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

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

Scanner类提供的判断功能

构造方法:

  • public Scanner(InputStream source) 创建键盘录入对象

  • 创建一个文本扫描器
    Scanner 对象名 = new Scanner(System.in) ;
    —>System类—变量名
    public static final InputStream in

  • 成员方法:

  • nextXXX():获取功能

  • public int nextInt() :录入int类型

  • public String nextLine() ;录入String类型

  • 判断功能:
    public boolean hasNextInt():判断录入的下一个数据是否为int类型,是,返回true,否则false
    public boolean hasNextLine():判断录入的下一个数据为一行内容

  • 键盘录入的时候先录入int,在录入String ----nextLine() ,这块会出现被漏掉(“回车符号”)

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

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

String类

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

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

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

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

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

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

面试题:

  • String s = new String(“hello”) ; 和String s = “hello” ; 有什么区别?分别创建了几个对象?
  • 区别
    前者:在堆内存中开辟空间,然后字符串值常量—指向常量池, 两个对象
    后者:推荐的方式,直接常量赋值,直接在常量池中找,有就返回地址,没有,开辟常量空间!
例题
public class StringDemo2 {
    public static void main(String[] args) {
        String s1 = new String("hello") ;
        String s2 = "hello" ;  //====> 拆分char[] chs = {'h','e','l','l','o'} --->String s2 = new String(chs)
        System.out.println(s1==s2) ; //false
        System.out.println(s1.equals(s2)) ;//true
        String s3=  "helloworld" ;
        String s4=  "HelloWorld" ;
        System.out.println(s2.equals(s3)) ;
        System.out.println(s3.equals(s4)) ;
        
         
       //String类已经重写 了Object的equals方法
       class String{
         
               private final char value[];
         
          public boolean equals(Object anObject) {  //s1.equals(s2)  //Object anObject =new String(字符数组)
            if (this == anObject) {   //判断s1和s2地址值是否相同
                      return true;
                  }
            if (anObject instanceof String) {   // 成立,
              String anotherString = (String)anObject;  //向下转型 String类型
           int n = value.length;                //int n  = s1.value.length= s1.length  = 5
            if (n == anotherString.value.length) {   //if(n == s2.length)    成立
            char v1[] = value;                   //v1[] = {'h','e','l','l','o'} ;
            char v2[] = anotherString.value;     //v2[] = {'h','e','l','l','o'} ;
            int i = 0;                           //统计变量 0
            while (n-- != 0) {
            if (v1[i] != v2[i])                 
            if(v1[0] !=v2[0])---->return false
                                  return false;
                             i++;                         //0--->1
                  }
               return true;
               }
           }
               return false;
          }
        }      
    }
}

String类相关的获取功能

  • 1)public char charAt(int index) :获取指定索引处的字符
  • 2)int length():获取字符串的长度
  • 3)public String concat(String str)拼接功能-- 将一个字符串拼接到指定字符串的后面(末尾追加)
  • 4)public String substring(int beginIndex):截取—>从指定位置开始截取,默认截取到末尾结束!
    public String substring(int beginIndex, int endIndex) 截取—>从指定位置开始截取到指定位置结束
    包前不包后(包含第一个位置,不包含最后一个位置,只能取到endIndex-1处)
  • 5)public String[] split(String regex):拆分(分割) ,按照指定的分割符将字符串拆分成字符串数组
  • 6)public int indexOf(int ch) :返回此字符第一次在字符串中出现的索引值
    public int lastIndexOf(int ch):返回此字符最后一次在字符串中出现的索引值
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)
  • 编码和解码必须一致,否则乱码
/* 需求:给定一个字符串,输入"Hellowold" ,输出 "hELLOWORLD"
 *
 * 1)可以录入字符串  s1
 * 2)将字符串的一个字符截取出来  s2
 *              substring(0,1) -->"H"----->转换小写 toLowerCase()
 * 3)     s1字符串  subString(1) ---->  "ellowold"--->转换成大写 toUpperCase()  --->s3
 * 4)  2)和3)结果----->concat拼接功能----->结果s4
 * 5) 输出
 *
 *
 * 键盘录入字符串:包含大写字母字符,数字字符,小写字母字符,统计每个字符出现的个数?(不包含特殊字符串)
 * 键盘录入字符串:将字符串反转 了
 *      输入"abc" --- >"cba"
 */
public class StringTest {
    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;

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

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

判断功能:
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

  • 空串,和空对象? 一样吗?
    不一样

20221115

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

String和StringBuffer/StringBuilder的区别?
  • String:是一个常量,一旦被赋值,其值不能被更改 ,不可变的字符序列!
  • 作为形式参数,形式参数的改变不影响实际参数(和基本类型作为形式参数传递的效果一致 ,特殊的引用类型)
  • StringBuffer:支持可变的字符串,线程安全的类—>同步的—>执行效率低
    StringBuffer的大部分功能—>synchronzied:同步锁(悲观锁)(多线程)
  • 作为形式参数,形式参数的改变直接影响实际参数
  • StringBuilder:和StringBuffer具备相互兼容的API,线程不安全的类—不同步的---->执行效率高
  • 单线程程序(只考虑效率)中,使用StringBuilder去替代StringBuffer
  • 多线程环境下(要考虑安全),使用StringBuffer
  • StringBuffer:线程安全的类,支持可变字符序列!
    int length()获取字符串缓冲区长度
    int capacity() :获取容量大小
 /* 键盘录入一个字符串,判断字符串是否为对称字符串?  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 ;
    }
}

StringBuffer的追加和插入

  • public StringBuffer append(任意Java类型):将指定的类型追加字符串缓冲区的序列中,返回自己本身
  • public StringBuffer insert(int index,String str/可以任意Java类型) 在指定位置处插入指定的数据,返回字符串缓冲区本身
  • StringBuufer的获取功能
    public char charAt(int index):获取字符串缓冲区中指定位置的字符,返回指定的字符
  • StringBuffer的删除
    StringBuffer delete(int start, int end) :删除从指定位置开始到指定位置结束(end-1)的字符,返回字符串缓冲区本身
  • StringBuffer deleteCharAt(int index):删除指定位置处的字符,返回值字符串缓冲区本身
  • StringBuffer的替换功能:
  • public StringBuffer replace(int start,int end,String str)
    将字符串缓冲区中的从指定位置开始到指定位置结束(end-1)的字符序列使用指定的字符串进行替换
  • StringBuffer的截取功能:
    public String substring(int beginIndex)
    public String substring(int beginIndex,int endIndex)
String---->StringBuffer ; StringBuffer---->String
public class StringBufferDemo {
    public static void main(String[] args) {

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

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


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

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

Integer与Character

Integer

Integer类:包装的int类型的值

  • 四类八种基本类型---------->包装类类型(引用类型) :jdk5以后的自动拆装箱
    byte Byte
    short Short
    int Integer
    long Long
    float Float
    double Double
    char Character
    boolean Boolean
    基本类型 引用类型 String

    String Integer int

自动拆装箱

Integer的构造方法:

  • public Integer(int value) :将int类型数据包装为Integer类型

  • public Integer(String s)throws NumberFormatException :将字符串类型包装Integer类型,如果字符串非数字字符串,

  • 就会出现NumberFormatExceptio数字格式化异常

  • jdk5以后的新特性:自动拆装箱 /静态导入(导入到方法的级别,前提方法必须为静态)/增强for循环/可变参数…

  • 基本类型会自动装箱为 引用类型: int–>Integer

  • 引用类型会拆箱为 基本类型 : Integer–>int

  • Integer 对象名 = 整数值;
    Integer 对象名 = new Integer(整数值) ;
    这两个不一样

Character

构造方法

  • Character(char value):包装一个char字符类型 char---->Character
  • 成员方法
    public static boolean isDigit(char ch):判断是否为数字字符
    public static boolean isUpperCase(char ch):判断是否为大写字母字符
    public static boolean isLowerCase(char ch):判断是否为小写字母字符

Date日期值

构造方法

  • Character(char value):包装一个char字符类型 char---->Character
  • 成员方法
    public static boolean isDigit(char ch):判断是否为数字字符
    public 值
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相关知识点

Date日期格式 ----->String日期文本 —>格式化操作

  • String日期文本
    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 ") ;//解析出问题了!

举例

 /* 键盘录入出生年月日 ,比如"1995-05-20" ,计算来到这个世界有多少天了?
 * 分析:
 *  1)键盘录入一个出生年月日--->String
 *  2)String日期文本---->解析java.util.Date日期对象
 *  3)获取你出生年月日的那个Date日期对象的时间毫秒值 long getTime()    oldTime
 *  4)获取当前系统时间毫秒值    newTime
 *          public static long currentTimeMillis() System类的静态方法
 *  5) long time = newTime-oldTime
 *  6) time/1000/60/60/24
 */
public class DateTest {
    public static void main(String[] args) throws ParseException {
        // 1)键盘录入一个出生年月日--->String
        Scanner sc = new Scanner(System.in) ;
        //提示并录入数据
        System.out.println("请输入一个数据: ") ;
        String birthday = sc.nextLine() ;

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

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

        //时间差值
        long time = newTime - oldTime ;
        System.out.println("您来到这个世界有"+(time/1000/60/60/24)+"天");
    }
}
自定义一个工具类:—构造私有化,外界不能new
  • 定义一个两个静态方法

  • 调用jdk提供的一个类的方法----如果这个方法本身throws 异常类名,我们必须处理!
    处理方式
    1)throws :抛出 (个人使用)
    2) 捕获异常 (开发中)
    try{
    可能出现问题的代码
    }catch(异常类名 对象名){
    对象名.printStackTrice();跟踪堆栈
    }

public class DateUtils {
    private DateUtils(){}

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

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

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

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

伪随机数

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

System类

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指定长度复制到目标数组中
针对小数精确计算 BigDecimal
  • 构造方法
    BigDecimal(String value):参数 “小数字符串值”
    BigDecimal(int value):整数
    BigDecimal(double value):浮动类型
  • 成员方法:
    public BigDecimal add(BigDecimal augend):加
    public BigDecimal subtract(BigDecimal subtrahend)减
    public BigDecimal multiply(BigDecimal multiplicand)乘
    public BigDecimal divide(BigDecimal divisor):除
    public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)
    参数1:除数值
    参数2:scale保留小数位数
    参数3:roundingMode舍入的模式 BigDecimal提供静态常量
日历类
  • java.util.Calendar :日历类—>是一个抽象类,不能new

  • 这个类里面的某些功能(静态功能)—一定完了这个类的子类的实例!
    创建日历实例—>public static Calendar getInstance()

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

  • Calendar提供成员方法:
    public int get(int field):获取日历的字段值
    参数就是需要通过Calendar访问的静态常量的那些字段
    public abstract void add(int field,int amount) 给日历字段设置偏移量,添加或者减去 amount值
    public final void set(int year,int month,int date) 设置日历字段

20221116

集合(重点)

collection

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

    }
}

collectio遍历
public class CollectionDemo2 {
    public static void main(String[] args) {
        //创建一个集合--->存储String
        Collection<String>  c  = new ArrayList<>() ;
        //添加字符串数据
        c.add("hello") ;
        c.add("world") ;
        c.add("javaEE") ;
        c.add("Mysql") ;
        System.out.println(c);

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

collection迭代器

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

  • Iterator<泛型> iterator()
    Iterator接口提供了功能:Object next() :获取下一个可以遍历的元素
    boolean hasNext():判断如果迭代器里面有元素,则返回true,然后在获取!
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,然后在获取!
        
                 ...//多次获取数据
                 
while(it.hasNext()){
            //有下一个元素
            //再获取
            String  s = it.next() ;
            System.out.println(s+"---"+s.length());
        }
    }
}

list(collection子接口)

  • List集合的特点
    允许集合元素重复(实际应用,List集合如何去重?),而且有序集合(存储和取出一致)
  • List集合的特有功能:
    void add(int index, E element):在指定位置插入新的元素
    E get(int index):获取指定位置处的元素
    E set(int index,E element):在指定位置处替换(修改)指定的元素
    ListIterator<泛型> listIterator():List集合的专有遍历–>列表迭代器
list遍历方式及添加等功能,增强for(重点)
public class ListDemo {
    public static void main(String[] args) {
        //创建List集合对象--存储String
        List<String> list = new ArrayList<>() ;

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

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

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


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

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

    }
}
list大集合套小集合表现形式

1)ArrayList<ArrayList> 大的集合创建出来
2)泛型---->ArrayList类型,子集合 ,创建3个子集合,每一个子集合都需要添加到大集合中
3)遍历大集合
for(ArrayList array:大的集合对象名){
for(Student s:array){
//获取到数据
}
}

20221117—20221118

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

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

LinkedList:

线程不安全,不同步,执行效率高
底层数据结构: 线程结构之链表,查询慢,增删快!

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

set集合(重点)

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

  • HashSet的底层依赖于HashMap(哈希表结构),元素唯一,迭代顺序无法保证的!
  • HashSet集合保证元素唯一—底层依赖HashMap的put方法---->依赖于hashCode()/equals()
  • 而现在存储String类型,重写了equals和hashCode(),保证元素唯一!
  • 创建HashSet集合对象
    HashSet<String> hs = new HashSet<>() ;
Treeset(红黑树)

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

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

TreeSet<String,Integer…> ts = new TreeSet<>();-------------->格式

举例(创建学生类排序由高到低)
//实现自然排序
public class Student  implements Comparable<Student>{
    private String name ;
    private int age ;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

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

    //重写方法
    @Override
    public int compareTo(Student s) {
        //存储s1-s8  s1就是作为根节点
        //主要条件:
        // 按照学生的年龄从小到大排序
      /*  int num = this.age -s.age ;
        //次要条件(自己分析):如果年龄相同,还要比较姓名是否一样的
        int num2 = (num==0)?(this.name.compareTo(s.name)):num;
        return num2;*/
        //主要条件:按照学生的姓名长度比较: 从小到大比较
        int num = this.name.length() - s.name.length() ;
        //次要条件:如果num==0,姓名长度一样,比较姓名内容是否一样
        int num2 = (num==0)?(this.name.compareTo(s.name)):num;
        //次要条件2:如果姓名长度一样,姓名内容也一样,还要比较年龄是否一样
        int num3 = (num2==0)?(this.age-s.age):num2;
        return num3 ;
    }
}
 /* TreeSet<Stdudent>,使用TreeSet存储自定义类型
 * 存储的Student类型实现Comparable,完成自然排序!
 *                  排序条件(主要条件)
 *                          按照学生的年龄从小到大排序
 *
 *                         自己的分析次要条件:
 *
 *
 *  使用TreeSet<Student>,按照自然排序排序
 *              主要条件:
 *                      按需学生的姓名的长度从小到大比较
 *
 *               次要条件:长度相同,比较姓名内容是否相同
 *
 *
 * 键盘录入5个学生姓名,数学成绩,英语成绩,语文成绩 ,按照学生的总分从高到到低排序!
 *
 *
 */
public class TreeSetDemo {
    public static void main(String[] args) {
        //创建TreeSet集合
        TreeSet<Student> ts = new TreeSet<Student>() ;//无参构造方法,自然排序

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

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

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

Map集合(与Collection不同)(重点)

  • Map和Collection的区别 ?
    Collection:单例集合,只能存储一种引用类型数据 遍历方式和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() :判断集合是否为空

遍历Map方法

  • 遍历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) ;
        }
    }
}

Map排序

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

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

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

常用的方法

  • 二分搜索法,在指定List集合中查询指定元素第一次出现索引值 (集合的元素有序)
  • public static int binarySearch(List<? extends Comparable<? super T>> list,T key)
  • public static T max(Collection<? extends T> coll):针对Collection集合获取最大值(自然顺序比较获取最大值)
  • public static T min(Collection<? extends T> coll):针对Collection集合获取最小值(自然顺序比较获取最小值)
  • public static void reverse(List<?> list):将List集合的元素反转
  • public static void shuffle(List<?> list):针对List集合随机置换
  • public static <T extends Comparable<? super T>> void sort(List list):针对List集合按照自然顺序排序
  • public static <T extends Comparable<? super T>> void sort(List list,Comparator com):
  • 针对List集合按照比较器进行排序

应用(斗地主洗牌看牌)举例

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

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

        System.out.println(pokerBox) ;

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

        //4)发牌
        //需要三个玩家,以及底牌---看成ArrayList
        ArrayList<String> player1 = new ArrayList<>() ;
        ArrayList<String> player2 = new ArrayList<>() ;
        ArrayList<String> player3 = new ArrayList<>() ;
        ArrayList<String> diPai = new ArrayList<>() ;
        /**
         *  三个玩家---->看成三个集合,每一个玩家就是ArrayList<String>
         *                      底牌--->也可以成集合
         *                     A--->B--->C
         */
        //遍历牌盒的里面的所有牌
        for(int x = 0 ; x < pokerBox.size()  ;x++){//0,53
            //规律:
            //底牌
            if(x>= pokerBox.size()-3){
                //给底牌添加元素
                diPai.add(pokerBox.get(x)) ;
            }else if(x%3==0){
                //这种情况里面的牌的给玩家1
                player1.add(pokerBox.get(x)) ;
            }else if(x%3==1){
                player2.add(pokerBox.get(x)) ;
            }else {
                //玩家3
                player3.add(pokerBox.get(x)) ;
            }
        }
        //看牌
        //三个玩家都可以看牌,可以看底牌
        lookPoker("李嘉图",player1) ;
        lookPoker("陈墨瞳",player2) ;
        lookPoker("芬格尔",player3) ;
        lookPoker("底牌",diPai) ;
    }
    //定义一个看牌的方法
    public static void lookPoker(String name,ArrayList<String> array){
        System.out.print(name+"的牌是:\t" ) ;
        //遍历牌(ArrayList)
        for(String s:array){
            System.out.print(s+" ") ;
        }
        System.out.println();
    }
}

20221119

多线程

程依赖于进程存在

  • 进程:能够调用系统资源的独立单位!(打开计算机任务管理器,查看进程状态)
    多进程:计算机都是支持多进程,提高CPU的使用率!
  • 开启多个进程的时候,玩游戏的同时可以听音乐,他们并不是同时进行的,而是一点时间片在两个进程之间进行高效切换!

线程:

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

   360软件---->开启---->开启进程
        同时清理内存---同时查杀病毒

多线程的意义:
多个线程在互相抢占CPU执行权! 线程的执行具有随机性!
1v3打篮球,3个人抢占篮球几率大,不一定(线程执行的是一个随机的)

JVM是多线程的吗?
是一个多线程的,至少有两条线程
main线程----用户线程
gc----->垃圾回收器 开启垃圾回收线程(回收没有更多的对象!)

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

  • 创建线程---->需要创建进程---->需要使用系统资源创建进程
    Java是不能够直接操作系统资源的,底层语言C是可以操作系统的
    Jdk提供了Thread类,里面有个start()---->执行线程—底层非Java语言实现的
  • 提供Thread类第一种创建线程的方式
    1)自定义一个类 继承的自Thread类
    2)重写Thread类的run方法---->完成一些的耗时的操作
    3)在main用户线程中,创建当前这个类对象
    4)开启线程---->不是run方法,run方法它只是一个普通方法(仅仅执行线程里面的内容:读文件/完成io的操作…)
  • 启动线程start()—>jvm是调用run线程的方法,结果是两个同时执行(具有随机性)
  • 启动线程,想知道哪一个线程执行数据—Thread类提供一些基本功能:
    public final void setName(String name):设置线程的名称
    public final String getName():获取线程名称

join与Yield

join:等待结束
Yeild:暂停并开始下一个

在python中 ,lst=['20221021', '20221024', '20221025', '20221026', '20221027', '20221028', '20221031', '20221101', '20221102', '20221103', '20221104', '20221107', '20221108', '20221109', '20221110', '20221111', '20221114', '20221115', '20221116', '20221117', '20221118', '20221121', '20221122', '20221123', '20221124', '20221125', '20221128', '20221129', '20221130', '20221201', '20221202', '20221205', '20221206', '20221207', '20221208', '20221209', '20221212', '20221213', '20221214', '20221215', '20221216', '20221219', '20221220', '20221221', '20221222', '20221223', '20221226', '20221227', '20221228', '20221229', '20221230', '20230103', '20230104', '20230105', '20230106', '20230109', '20230110', '20230111', '20230112', '20230113', '20230116', '20230117', '20230118', '20230119', '20230120', '20230130', '20230131', '20230201', '20230202', '20230203', '20230206', '20230207', '20230208', '20230209', '20230210', '20230213', '20230214', '20230215', '20230216', '20230217', '20230220', '20230221', '20230222', '20230223', '20230224', '20230227', '20230228', '20230301', '20230302', '20230303', '20230306', '20230307', '20230308', '20230309', '20230310', '20230313', '20230314', '20230315', '20230316', '20230317', '20230320', '20230321', '20230322', '20230323', '20230324', '20230327', '20230328', '20230329', '20230330', '20230331', '20230403', '20230404', '20230406', '20230407', '20230410', '20230411', '20230412', '20230413'], 其中每个元素都是日期。给出代码来输出包含每个月末日期的列表
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值