常用API, 包装类,StringBuilder,Math,System,Runtime,Bigdecimal,传统日期和时间,新增日期和时间,ArrayList,Lambda

Object类:

object类是所有类的祖宗类,因此java中所有类的对象都可以用Object类提供的方法

有三种比较常用的方法

clone() 创建并返回此对象的副本

//对象克隆
        //当某个对象调用这个方法时,这个方法会复制一个一模一样的新对象返回
//        浅克隆
        User u1=new User();
        User u2= (User) u1.clone();
        System.out.println(u1.getId());//500
        System.out.println(u2.getId());//500
        System.out.println(u1);
        System.out.println(u2);
//        u1与u2地址不同

clone是protected方法,不能被子类的对象调用要在子类中才能用,要想在不是Object的子类的类中使用需要在子类中重写clone方法,再让那个类继承子类

浅克隆指的是拷贝出的数据和原对象的数据一模一样,即只拷贝数据在堆中的地址

深克隆其它部分与浅拷贝一样,但是会重新创建一份数组对象

深克隆需要在重写的克隆方法中加上

User u2=(User)super.clone();
u2.scores=u2.scores.clone();
return u2;
@Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();

    }

只有实现了Cloneable接口的对象才能克隆

equals(Object o)//判断两个对象是否相等(判断地址)

Student s2=new Student("李华",23);
        System.out.println(s2.equals(s1));//重写前比较地址,重写后比较内容
        //equals判断字符串则比较内容,判断对象则比较地址
        System.out.println(s1==s2);
         //而“==”都是比较地址

 重写前equals比较地址,重写后比较内容

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }
//会顺带重写一个hashcode方法
//    @Override
//    public int hashCode() {
//        return Objects.hash(name, age);
//    }

toString()//返回对象的字符串表示形式

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

toString重写前表示地址,重写后表示内容

Student s1 = new Student("李华", 23);
        System.out.println(s1.toString());//toString变为灰色,意思是可以省略//Object_class.Student@4554617c
        System.out.println(s1);//Object_class.Student@4554617c

Objects类:

    public static void main(String[] args) {
        //Objects是一个工具类
        String s1=null;
        String s2="it";
          //System.out.println(s1.equals(s2));//如果其中一方为null则会出现空指针异常
        System.out.println(Objects.equals(s1, s2));//true//如果其中一方为null则不会出现空指针异常还能给出正确的结果false
        System.out.println("---------------------------------------------------------------------------");
//        isNull//判断一个对象是否为null是则返回true不是则返回false
        System.out.println(Objects.isNull(s1));
        System.out.println(Objects.isNull(s2));
        //isNull可以使用“==”替代
        System.out.println("---------------------------------------------------------------------------");
        //nonNull用于判断一个对象是否不是null
        System.out.println(Objects.nonNull(s1));
        System.out.println(Objects.nonNull(s2));
    }

 包装类:

byte-->Byte
short-->Short
int-->Integer
long-->Long
char-->Character
float-->Float
double-->Double
boolean-->Boolean
valueofv

自动装箱:


自动把基本类型转换为包装类型

Integer i2=13;

自动拆箱:

自动把包装类型转化为基本数据类型
int i3=i2;
ArrayList<Integer> list=new ArrayList<>();
        list.add(12);//12进行了自动装箱
        System.out.println(list.get(0)+1);//12进行了自动拆箱
        int i=list.get(0);//12进行了自动拆箱
        System.out.println(list.get(0)+1);

将基本类型数据转换成字符串:

//方法1:
        Integer a1=23;
        String rs1=Integer.toString(a1);//"23"
        System.out.println(rs1+1);//231
        //方法2:
        String rs2=a1+"";
        System.out.println(rs2+1);//231

将字符串转化为基本数据类型:

//方法1
//int
        String age="29";//必须是对应数值才能转对应基本类型
        int age1=Integer.parseInt(age);
        System.out.println(age1+1);
//double
        String scores="99.5";
        double b1=Double.parseDouble(scores);
        System.out.println(b1-50);

        //方法2
//        volueof
        int age2=Integer.valueOf(age);
        System.out.println(age2*2);
        double b2=Double.valueOf(scores);
        System.out.println(b2-90);

String:

StringBuilder:

相当于一个容器,他里面装的字符串是可以改变的,就是用来操作字符的
StringBuilder更适合对字符串的修改操作,效率会更高,代码也会更简洁
StringBuilder s = new StringBuilder();//s ""
        //创建一个空白的可变的字符串对象,不包含任何内容
        StringBuilder s1 = new StringBuilder("it");//s1 "it"
拼接:
s1.append("你是真牛皮");
        s.append("ivnbier");
        System.out.println(s1);//输出了字符串内容而不是地址,说明了StringBuilder重写了toString方法
        System.out.println(s);
        System.out.println("-------------------------------------------");

 s1输出it你是真牛皮
而s输出ivnbier

支持链式编程:
System.out.println(s.append(666).append("he2").append(666));
        System.out.println(s);//ivnbier666he2666
反转操作:
s.reverse();
        System.out.println(s);//6662eh666reibnvi
返回字符串长度:
System.out.println(s1.length());
把StringBuilder对象转换成Sting类型:
String rs=s.toString();
String rs1=s1.toString();
频繁的拼接修改建议用StringBuilder
操作字符串较少或不需要操作,以及定义字符串变量,建议用String
//需求:拼接100万次abc
        //String
//        String rs="";
//        for (int i = 1; i <= 1000000; i++) {
//            rs=rs+"abc";
//        }
//        System.out.println(rs);
        //效率非常的低,
        //StringBuilder
        StringBuilder rs1=new StringBuilder();
        for (int i = 0; i < 100000; i++) {
            rs1.append("abc");
        }
        rs1.toString();
        System.out.println(rs1);
        //效率高

StringBuffer:

StringBuffer用法和StringBuilder一模一样,
StringBuilder是线程不安全的而StringBuffer是线程安全的*
比如当很多用户一起进入系统,StringBuilder可能会出Bug
这时就要用到StringBuffer

StringJoiner:

在有些字符串中拼接字符串使用StringBuilder代码更麻烦
StringJoiner从JDK8才有,跟StringBuilder一样,也是用来操作字符串的
好处:不仅能提高字符串的操作效率,且在某些场景下使用它操纵字符串,代码会更简洁
构造器:
StringJoiner stj=new StringJoiner(",");//间隔符

stj.add("java1").add("java2").add("java3");
System.out.println(stj);//java1,java2,java3  说明间隔符自动添加在了中间
StringJoiner stj1=new StringJoiner(",","[","]");

stj1.add("java1").add("java2").add("java3");
System.out.println(stj1);//[java1,java2,java3]   添加了开始符号和结束符号

Math:

Math里面提供的都是对数据进行操作的静态方法

取绝对值:

Public static int abs(int a)
public static double abs(double a)

System.out.println(Math.abs(-12));//12
System.out.println(Math.abs(123));//123
System.out.println(Math.abs(3.14));//3.14

向上取整:

publc static double ceil(double a)
        System.out.println(Math.ceil(4.000000001));//5.0
        System.out.println(Math.ceil(4.000000000));//4.0

向下取整:

public static double floor(double a)
System.out.println(Math.floor(3.9999999999));//3.0

四舍五入:

public static long round(double a)
System.out.println(Math.round(3.499999999999999));//3  当小数点后有15个数时,输出3,再添一个9就输出4
System.out.println(Math.round(3.500000000000000000000));//4

取较大值与较小值:

        public static int max(int a,int b);取较大值
        public static int min(int a,int b);取较小值
        System.out.println(Math.max(5, 8));//8
        System.out.println(Math.min(5, 8));//5

取次方:

public static double pow(double a,double b);   取次方
        System.out.println(Math.pow(2, 3));//2的3次方  8.0
        System.out.println(Math.pow(3,2));//3的2次方  9.0

取随机数[0.0,1.0)包前不包后:

public static double random()  取随机数[0.0,1.0)包前不包后
System.out.println(Math.random());

System:

exit:终止运行

public static void exit(int status);
        //终止当前运行的虚拟机
        //按照惯例,非零代码表示异常终止
        System.out.println("-------------------------------------------------------------");
        //System.exit(0);//人为终止
        System.out.println("-------------------------------------------------------------");

获取当前系统的时间:

public static long currentTimeMillis();
//获取当前系统的时间
//返回的是long类型的时间毫秒值,从1970-1-1 0:0:0开始到此刻的总时间,1s==1000ms
//System.out.println(System.currentTimeMillis());
//可以用来计时:
可以用来计时:
long time1=System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
    System.out.println("输出了:"+i);

}
long time2=System.currentTimeMillis();
System.out.println("以上循环共花费了"+(time2-time1)/1000.0+"s");

Runtime:

Runtime是一个单例类

通过调用getRuntime方法获得对象而无法自己创建此类对象

Runtime r=Runtime.getRuntime();
//Runtime r1=new RunTime();不能自己创建runtime对象,只能用getRuntime来得到对象

runtime也有exit方法

Runtime r=Runtime.getRuntime();
//2.public static void exit(int status)
r.exit(0);//非零状态代码表示异常终止

availableProcessors()获取虚拟机当前运行的处理器数

//3.public int availableProcessors();获取虚拟机当前运行的处理器数
        System.out.println(r.availableProcessors());//16

totalmemory()返回Java虚拟机的内存总量

 //4.public long totalmemory()返回Java虚拟机的内存总量
        System.out.println(r.totalMemory()/1024.0/1024.0+"MB");//1024==1k,1024*1024==1m;//241.5MB

freememory()返回java虚拟机的空余内存

//5.public long freememory()返回java虚拟机的空余内存
        System.out.println(r.freeMemory()/1024.0/1024.0+"MB");//236.4599380493164MB

exec(String command)//启动某个程序并返回代表该程序的对象

//6.public Process exec(String command)//启动某个程序并返回代表该程序的对象
Process p=r.exec("\"C:\\Program Files (x86)\\Tencent\\QQ\\Bin\\QQScLauncher.exe\"");

Thread.sleep(xxx);让程序中暂停xxx毫秒秒后继续往下走

p.destroy();//销毁,关闭程序

单例设计模式复习:

单例设计模式
        //1.确保一个类只有一个对象
        //2.写法:
        // (1)把类的构造器私有
        //(2)定义一个类变量记住一个类的对象
        //(3)定义一个类方法,返回对象
//    单例应用场景:任务管理器,获取运行时对象
        //好处:可以避免浪费内存

Bigdecimal:

解决浮点型运算失真的问题

double a=0.1;
        double b=0.2;
        double c=a+b;
        System.out.println(c);//c==0.30000000000000004
        //这就是小数运算失真的问题

转化方法:

double d=0.1;
double e=0.2;

方法1:把它们变成字符串封装成BigDecimal对象来运算
BigDecimal b1=new BigDecimal(Double.toString(d));
BigDecimal b2=new BigDecimal(Double.toString(e));
方法2:把小数转化成那个字符串再得到BigDecimal对象运算(更简洁)
BigDecimal b1=BigDecimal.valueOf(d);
BigDecimal b2=BigDecimal.valueOf(e);

运算方法:

BigDecimal c1=b1.add(b2)//加法
BigDecimal c2=b1.substract(b2)//减法
BigDecimal c3=b1.multiply(b2)//乘法
BigDecimal c4=吧。divide(b2)//除法
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
//直接输出了算出的值,证明这里修改了toString方法
double f=0.1;
double g=0.3;
BigDecimal b3=BigDecimal.valueOf(f);
BigDecimal b4=BigDecimal.valueOf(g);
BigDecimal c5=b3.divide(b4,2, RoundingMode.HALF_UP);//精确度,舍入模式
System.out.println(c5);//0.33
c5.doubleValue();//将c5转换成double类型的数据
System.out.println(c5);

传统日期和时间:

Date:

1.创建一个date对象,代表当前时间信息
Date d=new Date();
System.out.println(d);//Tue Nov 07 08:55:04 GMT+08:00 2023
2.gettime拿到时间毫秒值
long time=d.getTime();
        System.out.println(time);//1699604901689
3.public Date(long time)把时间毫秒值转化为date日期对象
Date d2=new Date(time);
        System.out.println(d2);//Tue Nov 07 08:55:04 GMT+08:00 2023
4.获得当前时间往后两秒后的Date时间:
time+=2*1000;
        Date d3=new Date(time);
        System.out.println(d3);
5.用setTime修改date日期对象的时间
Date d4=new Date();
d4.setTime(time);
System.out.println(d4);

SimpleDateFormat:

能够将Date得到的事件对象格式化成指定的时间形式

y  年
M  月
d  日
H  时
m  分
s  秒
EEE 星期几
a  上午/下午

简单日期格式化
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss EEE a");
Date d=new Date();
        long time=d.getTime();
        String s=sdf.format(d);//   format方法可以接收Date对象//2023-11-10 16:36:01 星期五 下午
System.out.println(s);
        String s2=sdf.format(time);//   format方法可以接收毫秒值
        System.out.println(s2);
解析字符串,将其转化为Date对象
        Date d2;
        String time2="2022-11-11 08:59:55";
        SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        d2=sdf2.parse(time2);
        System.out.println(d2);//Fri Nov 11 08:59:55 GMT+08:00 2022

Calendar:

代表系统此刻时间对应的日历.

通过类方法得到日历对象:
Calendar now=Calendar.getInstance();//
获取日历中的某个信息
int information=now.get(Calendar.WEEK_OF_YEAR);
修改日历中的某个信息
int information1=now.get(Calendar.WEEK_OF_YEAR);

 加减法

now.add(Calendar.WEEK_OF_YEAR,8);//一年有52周,而44+8==52;所以这里加的数大于8的话就会进位,例如输入9的话输出1
now.add(Calendar.WEEK_OF_YEAR,-51);//设置负数用于减去某值//与上方同理,减去52的话就会退位,输出53

新增日期和时间:

LocalDate

对应年月日

System.out.println(ld);//年 月 日
ld.withYear(2099);//修改年份//按ALT+回车再回车,快速补全前面部分
ld.getYear();//年
ld.getMonthValue();//月:(1-12)
ld.getDayOfMonth();//日
ld.getDayOfYear();//一年的第几天
int dayofweek=ld.getDayOfWeek().getValue();//星期几
System.out.println("星期"+dayofweek);
直接修改某个信息:withYear,withMonth,withDayOfMonth,withDayOfYear
LocalDate ld1 = ld.withYear(2099);
System.out.println(ld1);

把某个信息加多少:plusYears,plusMonths,plusDays,plusWeeks
LocalDate ld2=ld.plusDays(2);
System.out.println(ld2);

把某个信息减多少:minusYears,minusMonths,minusDays,minusWeeks
LocalDate ld3=ld.minusDays(2);
System.out.println(ld3);

获取指定日期的LocalDate对象:public static LocalDate of(int year,int month,int dayofmonth);
LocalDate ld4=LocalDate.of(2023,11,7);
System.out.println(ld4);

判断两个日期对象是否相等,在前还是在后?equal isBefore isAfter
System.out.println(ld.equals(ld4));//true
System.out.println(ld.equals(ld2));//false
System.out.println(ld.isBefore(ld3));//false
System.out.println(ld.isBefore(ld2));//true
System.out.println(ld.isAfter(ld2));//false
System.out.println(ld.isAfter(ld3));//true

LocalTime:

对应时分秒,除了名称改变外方法用法几乎没有变化

此外还拥有纳秒

lt.getNano();//纳秒
//1(Second)==1E9(nanoOfScond)

LocalDateTime:

总结就是前面两个的方法它都管用
并且用法不变

额外有一个:

把LocalDateTime转换成LocalDate和LocalTime
//public LocalDate toLocalDate();
//public LocalTime toLocalTime();
//public static LocalDateTime of(LocalDate date,LocalTime time)
LocalDate ld=ldt.toLocalDate();
System.out.println(ld);
LocalTime lt=ldt.toLocalTime();
System.out.println(lt);
合并成LocalDateTime对象:
LocalDateTime ldt2 = LocalDateTime.of(ld, lt);
        System.out.println(ldt2);
        System.out.println(ldt2.equals(ldt));

Zone:

ZoneId:代表时区id

ZoneId zoneId=ZoneId.systemDefault();//获取系统默认的时区
        System.out.println(zoneId.getId());//GMT+08:00
        System.out.println(zoneId);//GMT+08:00

证明.getId可以省略

获取java支持的全部时区id
//public static Set<String> getAvailableZoneIds()//
System.out.println(ZoneId.getAvailableZoneIds());//按住CTRL+F来寻找
把某个时区id封装成ZoneId对象
//public static ZoneId of(String zoneId)//把某个时区id封装成ZoneId对象
ZoneId zoneId1=ZoneId.of("America/New_York");
System.out.println(zoneId1);

ZonedDateTime:带时区的时间

获取某个时区的ZonedDateTime对象
//public static ZonedDateTime now(ZoneId zone):获取某个时区的ZonedDateTime对象
ZonedDateTime now = ZonedDateTime.now(zoneId1);
System.out.println(now);
获取世界标准时间
ZonedDateTime now1=ZonedDateTime.now(Clock.systemUTC());
System.out.println(now1);
获得系统默认时区的时间
ZonedDateTime now2=ZonedDateTime.now();
System.out.println(now2);

Istant:

创建对象:
Instant now = Instant.now();
 获取此刻时间信息:标准时间
System.out.println(now);//获取此刻时间信息:标准时间
 获取总秒数
        //获取总秒数
        long second = now.getEpochSecond();
        System.out.println(second);//从1970-01-01T00:00:00走到现在的总秒数
 获取不够1秒的纳秒数
        //获取不够1秒的纳秒数
        int nano = now.getNano();
        System.out.println(nano);
加法 
//加法
Instant now1 = now.plusNanos(111);//返回了一个新的Instant对象,证明是一个不可变对象
减法
//减法
        Instant now2 = now.minusNanos(111);
Instant对象的作用:做代码的性能分析或者记录用户的操作时间点 
//Instant对象的作用:做代码的性能分析或者记录用户的操作时间点
        Instant now3 = Instant.now();
        //代码执行。。。。。。。。。。。。。。。。。。。。。。。。。
        Instant now4 = Instant.now();
        //以此来分析中间代码花了多长时间

DateTimeFormatter:

格式化器:

首先创建一个日期时间格式化对象

y  年
M  月
d  日
H  时
m  分
s  秒

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
对时间进行格式化
LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
方法1:
String rs = formatter.format(now);
        System.out.println(rs);
方法2:
String rs1 = now.format(formatter);
System.out.println(rs1);
解析时间:

一般用LocalDateTime提供的解析方法来解析

String datesTr="2024年11月08日 09:40:50";
        //如果输入String datesTr="2024年11月8日 9:40:50";就会出错
        LocalDateTime ldt = LocalDateTime.parse(datesTr, formatter);
        System.out.println(ldt);

period

年,月,日
计算两个localdate对象相差的年数,月数,天数

LocalDate ld1 = LocalDate.of(2023, 11, 25);
        LocalDate ld2 = LocalDate.of(2024, 12, 28);
        Period period = Period.between(ld1, ld2);
        int years = period.getYears();
        System.out.println(years);
        int months = period.getMonths();
        System.out.println(months);
        int days = period.getDays();
        System.out.println(days);

Duration:

差的天数,小时数,分数,秒数,纳秒数

,支持LocalTime,LocalDateTime,instant。

 public static void main(String[] args) {
        LocalDateTime start = LocalDateTime.now();
        LocalDateTime end = LocalDateTime.of(2023, 11, 11, 7, 30, 10);
        java.time.Duration duration = java.time.Duration.between(start, end);
        System.out.println(duration);
        System.out.println(duration.toDays());
        System.out.println(duration.toHours());
        System.out.println(duration.toMillis());//毫秒
        System.out.println(duration.toMinutes());
        System.out.println(duration.toNanos());//纳秒
        System.out.println(duration.toString());

Arrays:

返回数组的内容

double a[]={1,2,3,4,5,6,7,8,9};
        String s = Arrays.toString(a);
        System.out.println(s);//[1, 2, 3, 4, 5, 6, 7, 8, 9]


拷贝数组数据,可以将其交到一个新数组里面(包前不包后)
       

double[] a1 = Arrays.copyOfRange(a, 1, 8);
        System.out.println(Arrays.toString(a1));//[2, 3, 4, 5, 6, 7, 8]


拷贝数组交到一个新数组里面,自定义其长度

double[] a2=Arrays.copyOf(a,10);


新数组多出的空间用默认值0填充
       

System.out.println(Arrays.toString(a2));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]


若新数组缺少空间那就只拷贝前面的
       

double[] a3=Arrays.copyOf(a,5);
        System.out.println(Arrays.toString(a3));//[1, 2, 3, 4, 5]


        //把数组中的原数据改为新数据
        //例子:打八折
 

        Arrays.setAll(a, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int value) {
                BigDecimal bd1 = BigDecimal.valueOf(a[value]);
                BigDecimal bd2 = BigDecimal.valueOf(0.8);
                BigDecimal n=bd1.multiply(bd2);
                double m=n.doubleValue();
                return m;
          }
        });

Lambda简化

 Arrays.setAll(a, (int value) ->{
                BigDecimal bd1 = BigDecimal.valueOf(a[value]);
                BigDecimal bd2 = BigDecimal.valueOf(0.8);
                BigDecimal n=bd1.multiply(bd2);
                double m=n.doubleValue();
                return m;
        });
        System.out.println(Arrays.toString(a));//[0.8, 1.6, 2.4, 3.2, 4.0, 4.8, 5.6, 6.4, 7.2]


        //对数组进行升序排序:
       

int b[]={5,848,8,8,56,4,5};
        Arrays.sort(b);
        System.out.println(Arrays.toString(b));//[4, 5, 5, 8, 8, 56, 848]


        //如果数组中存储的数据是对象,能否排序?

        Student[] students=new Student[4];
        students[0]=new Student("小华",18,180.4);
        students[1]=new Student("小米",19,191.4);
        students[2]=new Student("小刚",18,185.8);
        students[3]=new Student("老六",66,666.6);
        System.out.println(Arrays.toString(students));//四个地址
        //Arrays.sort(students);
        //System.out.println(students);//执行后报错
        //Arrays.sort(students);
        //System.out.println(Arrays.toString(students));
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //约定1.认为左边对象 大于 右边对象 返回正整数
                //约定2.认为左边对象 小于 右边对象 返回负整数
                //约定1.认为左边对象 等于 右边对象 返回零
                //或者:
                return Double.compare(o1.getHeight(), o2.getHeight());
                //若要降序就将o1与o2换位置
            }
        });
        System.out.println(Arrays.toString(students));

Lambda:

//用于简化匿名内部类的代码写法
//只能简化函数式接口的匿名内部类//只能有一个抽象方法,还要是接口
//将来见到的大部分函数式接口上面都可能会有一个@Functionallnterface的注解,有该注解就必定是函数式接口

//Lambda表达式进一步简化
/**
* 1.参数类型可以省略不写
* 2.如果只有一个参数 ()也可以省略
* 3.如果Lambda表达式中的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号!此时,若此行代码是return语句,也必须去掉return不写
* 4.3中最后的分号保留
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值