java第七周学习笔记:

这篇博客详细介绍了Java的基础知识,包括Character类的构造方法和成员方法,如isDigit和isLowerCase;Date类的使用,包括日期格式转换;Calendar类的成员变量和获取日期字段的方法;System类的静态功能如gc和currentTimeMillis;Math类的数学运算工具,如abs和sqrt;Random类的随机数生成;以及BigDecimal的精确计算。此外,还涵盖了选择排序、集合概念、List集合的遍历和子类ArrayList, Vector, LinkedList的特性。" 37958595,906030,C语言实现字符串替换函数,"['C语言编程', '字符串操作', '算法实现']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Character类
1.1概念

Charaacter:Character类是基本数据类型char类型的包装类类型,包含char的值;此外,该类还提供了

几种方法来确定字符的类别(小写字母,数字等),并将字符从大写转换为小写,反之亦然。
1.2构造方法

Character(char value) :参数里面也可以为int<int---char> :将一个字符内容构造成包装类类型
1.3成员方法

<1>public static boolean isDigit(char ch):判断当前ch字符是否为数字

<2>public static boolean isLowerCase(char ch):判断当前ch字符是否为小写字母字符

<3>public static boolean isUpperCase(char ch)确定指定的字符是否为大写字符。
2.Date类
2.1概念

java.util.Date:表示日期格式:精确到瞬间毫秒.
2.2构造方法

<1>public Date():无参构造方法,获取当前系统时间的日期格式,默认使用当前系统时间.

<2>public Date(long date):将long类型-构造成Date对象:long指定时间毫秒值(与1970年1月1日).
2.3成员方法

public long getTime():将Date日期格式----转换成long类型返回自1970年1月1日以来的Date毫秒数
2.4String日期文本格式和Date格式之间的转换

public final String format(Date date):  将日期格式化成日期/时间字符串

public SimpleDateFormat(String pattern):参数为描述日期和时间格式的一种模式

public Date parse(String source) 解析方法,可能出现解析异常,当前字符串开头不能解析就出问题.

(1)Date-----String

<1>创建日期对象

<2>创建SimpleDateFormat对象:中间桥梁,格式化/解析工具

<3>利用public final String format(Date date)完成转换

    Date date = new Date() ;//1
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;//2
    String dateStr = sdf.format(date);//3

(2)String-----Date

<1>创建String文本

注意:当前的SimpleDateFormat的模式必须和字符串文本格式对应!,否则解析出问题

<2>创建SimpleDateFormat对象

<3>利用public Date parse(String source)解析完成

    String sourc = "2008-5-12" ;//1
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd" ) ;//2
    Date date2 = sdf2.parse(sourc);//3

3.Calendar类
3.1概念

java.util.Calendar:为抽象类;表示的是特定一组时间:诸如YEAR,MONTH,DAY_OF_MONTH 等等.
3.2成员变量

Calendar成员变量为常量;

<1>public static final int YEAR :年

<2>public static final int MONTH:月:角标是从0开始计算, 计算出来+1

<3>public static final int DATE:月中的日期 和DAY_OF_MONTH同义词

其余查看API获取时分秒
3.2Calendar实例化

Calendar calendar = new Calendar();构建具有默认时区和默认的FORMAT语言环境的日历.

如果一个类定义为抽象类,那么目的是不让这个类实例化,它肯定会有静态功能,返回值它本身.

public static Calendar getInstance():  使用默认时区和区域设置获取日历;Calendar返回的

是基于默认时区的当前时间.
3.3成员方法

<1>public int get(int field):获取当前的日历字段

<2>public abstract void add(int field,int amount):设置时间偏移量,针对当前日历字段,减去或者添加

指定amount(偏移量).

<3>public final void set(int year,int month,int date):设置日历字段中的值YEAR;MONTH;DAY_OF_MONTH

月份从0开始.

    Calendar calendar = Calendar.getInstance();//创建日历对象
    int year = calendar.get(Calendar.YEAR) ;//获取当前日历字段
    int month = calendar.get(Calendar.MONTH) ;
    int date = calendar.get(Calendar.DATE) ;
    calendar.add(Calendar.YEAR,5) ;//设置偏移量
    year = calendar.get(calendar.YEAR) ;

4.System类
4.1概念

System类:不能实例化;里面提供一些标准输入流.
4.2静态字段---常量

<1>public static final  InputSteam in ;字节输入流

<2>public static final  PrintStream out ;字节输出流
4.3静态功能

<1>public static void gc():手动开启垃圾回收器

<2>public static void exit(int status):参数为0,正常终止JVM

<3>public static void arraycopy(Object src,int srcPos,Object dest,int destPos, int length)复制数组

<4>public static long currentTimeMillis():计算当前系统时间毫秒值
5.Math类
5.1概念

java.lang.Math: 数学的运算工具类;都是静态的功能.
5.2常用功能

<1>public static double abs(double/int a):求绝对值

<2>public static double ceil(double a):向上取整

<3>public static double floor(double a):向下取整

<4>public static double max(double a,double b):获取最大值

<5>public static double min(double a,double b):获取最小值

<6>public static double random():(0,1) :获取0,1之间随机数

<7>public static long round(double a):四舍五入

<8>public static double sqrt(double a):开正方根

<9>public static double pow(double a,double b):a的b次幂

注意:jdk5以后新特性:静态导入,可变参数,自动拆装箱,增强for循环,枚举

import java.util.Scanner ; //类级别

import  static java.lang.Math.abs ;//方法级别
6.Random类
6.1概念

 java.util.Random:伪随机数生成器
6.2构造方法

<1>Random():创建随机数生成器,通过它调用功能获取的随机数是不同的.

<2>Random(long seed):创建随机数生成器,通过它调用功能,产生随机数值相同的
6.3成员方法

<1>public int nextInt():获取随机数int类型范围

<2>public int nextInt(int n):获取0-n之间随机数,不包括n
7.BigDecimal类
7.1概念

java.math.BigDecimal:对小数进行精确计算.
7.2构造方法

<1>public BigDecimal(String val) :将数字字符串构造成BigDecimal对象

<2>public BigDecimal(int val):将int转换为BigDecimal
7.3常用方法

<1>public BigDecimal add(BigDecimal augend)求和

<2>public BigDecimal subtract(BigDecimal subtrahend)相减

<3>public BigDecimal multiply(BigDecimal multiplicand):乘

<4>public BigDecimal divide(BigDecimal divisor)除

<5>除的时候,还可以保留小数的精确位数

public BigDecimal divide(BigDecimal divisor,int scale, RoundingMode roundingMode)

参数1:指定的除数;参数2:保留的有效位数;参数3:指定舍入模式: ROUND_HALF_UP 四舍五入
8.选择排序
8.1选择排序思想

思想:使用0角标对应的元素依次和后面角标对应的元素进行比较,小的往前放,第一次比较完毕最小

值出现在最小索引处,依次比较,比较的次数:数组长度-1次.
8.2代码实现

    for(int i = 0;i < arr.length-1;i++){
                for(int j = i + 1;j < arr.length;j++){
                    if(arr[i] > arr[j]){
                        int temp = arr[i];
                        arr[i] = arr[j];
                        arr[j] = temp;
                    }
                }
    }

9.Collection集合
9.1集合的概念

集合: 一种容器,能够存储引用数据类型的容器,长度可变.
9.2Collection基本功能

<1>boolean add(Object e):添加任意类型

<2>boolean remove(Object o):删除指定的元素

<3>void clear():暴力删除,将集合中所有元素删除

<4>boolean contains(Object o):判断集合中是否包含指定的元素

<5>boolean isEmpty():判断是否为空,不为空,false;空,true

<6>int size():获取集合的元素数
9.3集合和数组的区别

(1)长度的区别

数组长度:固定     集合长度:可变

(2)存储数据类型区别

数组:既可以存储基本数据类型,而且存储引用数据类型

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

(3)存储元素区别

数组:既可以存储基本数据类型,而且可以存储引用数据类型,元素类型必须统一

集合:虽然只能存储引用数据类型,但是没有泛型<>情况下可以存储任何引用类型, 模拟数组的特点.
9.4集合高级功能

<1>boolean addAll(Collection c):添加一个集合中的所有元素

<2>boolean containsAll(Collection c):包含一个集合的所有元素:包含所有算包含

<3>boolean removeAll(Collection c):删除一个集合中包含另一个集合中的某个元素,就算删除,返回

true

<4>boolean retainAll(Collection c):将交集的元素保存A集合中,boolean表达的意思:将保存在A集合

中的元素是否和之前的元素发生变化,如果前后发生变化,则返回true;没有变化,则返回false.
9.5泛型

(1)泛型就是集合对象在创建同时明确数据类型,并且将运行时期异常提前到编译时期(模拟数组定

义).使用<引用数据类型>

(2)泛型的好处:

<1>提高程序安全性

<2>解决黄色警告线

<3>使用集合的迭代器避免强制类型转换

    Collection<String> c = new ArrayList<>() ;
    后面的<>可以写上,也可以不写;jdk7以后泛型推断:默认的认为前后类型一致

(3)JDK5以后,提供了<E>泛型,提高程序安全性,将运行时期异常,提前编译时期,

(4)泛型的定义方式

<1>泛型定义在类上

    public class ObjectTool<T> {}
    ObjectTool<String> ot = new ObjectTool<>() ;
    ot.show("hello") ;
    ObjectTool<Integer> ot2 = new ObjectTool<>() ;
    ot2.show(100) ;

<2>将泛型定义在方法上

    public <T> void show(T t){}
    泛型定义在方法上的格式:权限修饰符 <T> 返回值类型 方法名(T 参数名){}

<3>将泛型定义在接口上

1)接口的子实现类已经明确了类型

明确了泛型,集合添加只能当前类型,直接添加不了其他类型,后期通过反射

    public interface Inter<T> {
        void show(T t) ;
    }
    情况1:接口的子实现类已经明确了类型
    public class InterImpl<String> implements Inter<String> {
        @Override
        public void show() {
            System.out.println("show InterImpl...");
        }
    }
     
    Inter<String> inter = new InterImpl<>() ;
    inter.show();

2)接口的子实现类不明确里面存储的类型

    情况2:子实现类不明确泛型的类型
    public class InterImpl<T> implements Inter<T>{
        @Override
        public void show(T t) {
            System.out.println(t) ;
        }
    }
     
    Inter<Integer> inter = new InterImpl<>() ;
    inter.show(100) ;
    Inter<String> inter2 = new InterImpl<>() ;
    inter2.show("helloworld") ;

(5)泛型的通配符

<1><?>:代表Object或者任意的Java类型(jdk提供/自定义的)

<2><? extends E>:向下限定,E这个类型以及它的子类

<3><? super E> :向上限定,E这个类以及它的父类
10.迭代器
10.1概念

迭代器是集合专有的遍历方式;迭代器是接口,是通过ArrayList的内部类来实现他里面的hasNext()和next().
10.2面试题:为什么将迭代器不定义为一个类,而是接口?

如果是类,使用继承的特点,子类继承父类,可以继承父类非私有的成员,继承具有局限性,不仅获取到

了需要的,其他不需要的也获取过来了;提供接口,面向接口编程,提高功能扩展,谁实现了接口,就具备

当前这个额外功能.
10.3迭代器的使用

Iterator<E> iterator():迭代器:集合专有遍历方式

Iterator:接口<1>boolean hasNext() 判断是否有下一个可以迭代的元素 (判断功能)

                   <2>Object next():获取下一个可以迭代的元素(获取功能)

    Collection c = new ArrayList() ;
    c.add("hello") ;
    c.add("world") ;
    c.add("java") ;
    Iterator it = c.iterator();
     while(it.hasNext()){
        String s = (String) it.next();
        System.out.println(s+"---"+s.length());
    }

注意:next()使用的时候,不能使用多次,否则造成数据丢失.
11.List集合
11.1List集合的特点

有序:存储和取出一致;元素可以重复.
11.2List集合特有功能

<1>void add(int index, Object element):在指定位置处添加一个新的元素

<2>Object remove(int index):删除指定位置处的元素

<3>E set(int index, Object element):修改指定位置处的元素内容

<4>Object get(int index):获取指定位置处的元素

<5>ListIterator<E> listIterator():列表迭代器

ListIterator接口:

boolean hasNext() :判断当前列表中是否有下一个可以遍历的元素

Object next():获取下一个元素

boolean hasPrevious():判断当前列表中是否有上一个可以遍历的元素

Object previous():获取上一个元素

注意:前提条件:必须有正向遍历,才能使用反写遍历;
11.3List集合5种遍历方式

    方式1:Collection集合的toArray()----Object[]
    List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("world");
        list.add("javaee");
        Object[] objects = list.toArray();
        for(int i = 0;i < objects.length;i++){
            String s = (String)objects[i];
            System.out.println(s+"---"+s.length());
        }

    方式2:Coillection集合的Iterator迭代器
    Iterator<String> iterator = list.iterator();
    while(iterator.hasNext()){
        String next = iterator.next();
        System.out.println(next);
    }
     

    方式3:get(int index) + size() 的普通for循环
    for(int i = 0;i < list.size();i++){
        String s = list.get(i);
        System.out.println(s);
    }

    方法4:使用列表迭代器
    ListIterator<String> stringListIterator = list.listIterator();
    while(stringListIterator.hasNext()){
        String next = stringListIterator.next();
        System.out.println(next);
    }

    方法5:增强for循环
    for(泛型数据类型 变量名 : 集合对象名称){
        输出变量名;
    }
     
    for(String s:list){
        System.out.println(s);
    }

11.4典型例题

(1)使用List存储字符串数据,遍历这个list集合,如果当前元素内容有"world",需要给List中添加一个新

的元素"php".

java.util.ConcurrentModificationException 并发修改异常

解决方案:<1>使用集合判断,使用集合添加或者修改

                <2>使用迭代器,使用迭代器添加/修改

    for(int x = 0 ; x < list.size() ; x ++){
        String s = list.get(x) ;
                判断
            if("world".equals(s)){
                    集合添加
                list.add("php");
            }
    }
    System.out.println(list);

    使用ListIterator列表迭代器中添加功能void add(E e)
    ListIterator<String> listIterator = list.listIterator();
    while(listIterator.hasNext()){
                获取
        String s = listIterator.next();
        if("world".equals(s)){
                    迭代器添加
            listIterator.add("php"); 在指定元素后面插入
        }
    }

(2)使用List存储多个字符串,有重复元素,如何去重

     List<String> newList = new ArrayList<>() ;
            遍历旧集合获取每一个元素:增强for
        for(String s:list){
                在新集合中判断是否包含这个元素,如果不包含,才给新集合中添加
            if(!newList.contains(s)){
                newList.add(s) ;
            }
         }
            遍历新集合
        for(String s:newList){
            System.out.println(s);
        }
    }

    方式2:选择排序思想
    for(int x = 0 ; x < list.size()-1; x++){
        for(int y = x+1 ; y < list.size() ; y ++){
                    业务思想:如果前面的元素和后面元素一致,将后面的重复元素删除掉
             if(list.get(y).equals(list.get(x))){
                        将后面的元素删除
                list.remove(y) ;
                y -- ;
            }
        }
    }
            遍历当前这个集合
    for(String s :list){
        System.out.println(s);
    }

12.List集合子实现类

 ArrayList:底层数据结构是数组,数组的特点:查询快,增删慢.从线程角度考虑:由于实现是不同步的,执

行效率高,线程不安全.默认容量为10个,以1.5倍扩容.

 Vector:底层数据结构是数组,查询快,增删慢.线程角度:实现同步的,里面的成员方法大部分都会有

synchronized同步锁,保证安全性安全性很高,但是执行效率低,单线程程序中,使用ArrayList替代

Vector.

LinkedList:底层数据结构是一个链表,线程角度:不同步的,单线程中执行效率高,安全性低!链表:数据

域和指针域组成.
12.1ArrayList

(1)构造方法:

<1>public ArrayList():构造一个初始容量为十的空列表

<2>public ArrayList(int initialCapacity):指定容量大小

(2)ArrayList嵌套for使用

    ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ;
    for(ArrayList<Student> array :bigArray){
        for(Student s :array ){
            System.out.println(s.getName()+"\t"+s.getAge());
        }
    }

12.2Vector

(1)Vector集合:在List集合中最明显的特点:线程安全

(2)特有功能

<1>public void addElement(Object obj):添加元素

<2>public boolean removeElement(Object obj):直接从Vector集合中删除指定的元素

<3>public Object elementAt(int index):通过指定的索引值获取元素

<4>public Enumeration<Object> elements():(特有迭代器)获取Vector集合中的枚举组件接口---------------类似于public Iterator iterator():迭代器

boolean hasMoreElements()  ---->类似于   boolean hasNext() 判断是下一个遍历的元素

Object nextElement()     ---类似于    Object next()     获取下一个元素

(5)Vector集合另两种遍历方式

    使用特有功能: public Object elementAt(int index) +size()
    for(int x = 0 ; x < v.size() ; x ++){
        String s = v.elementAt(x);
        System.out.println(s) ;
    }

    public Enumeration<Object> elements():(特有迭代器)获取Vector集合中的枚举组件接口
    Enumeration<String> en = v.elements();
    while(en.hasMoreElements()){
        String s = en.nextElement();
        System.out.println(s) ;
    }

12.3LinkedList

(1)LinkedList:不同步,线程不安全,执行效率高; 数据结构是:链表

(2)特有功能

<1>public void addFirst(Object e):在链表开头插入元素

<2>public void addLast(Object e):将元素追加到链表的末尾

<3>public Object getFirst():获取链表的第一个元素

<4>public Object getLast():获取链表的最后一个元素

<5>public Object removeFirst():删除链表第一个元素并获取第一个元素

<6>public Object removeLast():删除链表最后一个元素并获取
13.Set集合子实现类

Set集合:无序.保证元素唯一
13.1HashSet

(1)HashSet:底层一个HashMap的实例,保证元素唯一(底层哈希表,和HashMap有关系),不能保证迭

代顺序恒久不变.

(2)Hash面试题:为什么HashSet<String>,添加重复的String数据,能够将元素唯一?

答:hashSet集合的添加功能add方法间接依赖于HashMap的put方法,底层依赖于hashCode()和

equals()方法;首先,要比较当前存储String类型数据的哈希码值是否相同,如果相同,比较是内容是否

一样,调用equals()方法,String类型已经重写了Object,比较内容.
13.2TreeSet

TreeSet<E>:底层依赖于TreeMap;是Red-Black-Tree数据结构:红黑树(自平衡的二叉树结构);有

两种排序:自然排序/比较器排序,取决于构造方法.

TreeSet集合的两种排序方式

<1>public TreeSet()构造一个新的,空的树组,根据其元素的自然排序进行排序;要实现自然排序,当

前存储对象的类型必须实现Comparable接口.

    public class Student implements Comparable<Student>{
         @Override
        public int compareTo(Student s) {   需要后面的元素的年龄和当前根节点元素年龄的比较
            int num = this.age - s.age ;  三元运算
            int num2 = (num==0)?(this.name.compareTo(s.name)):num ;
            return num2;
        }
    }
     
    TreeSet<Student>  ts = new TreeSet<>() ;   创建TreeSet集合对象
    后续添加遍历

<2>TreeSet集合的另一种排序:比较器排序:  public TreeSet(Comparator<? super E> comparator)

Comparator<T> 接口中有一个抽象方法:  int compare(T o1,T o2)

    TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
        @Override
        public int compare(Student s1, Student s2) {
        int num = s1.getAge() - s2.getAge() ;  主要条件:学生的年龄从小到大排序
                  次要条件:年龄相同的,按照学生的姓名:字典顺序比较
        int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ;
        return num2 ;
        }
    }) ;
     
    后续添加遍历操作

14.Map

Map是Java提供的另一种方式Map<K,V>:K 键,V 值----存储一系列的键值对元素.
14.1Map特点

map集合特点就是采用了 Key-value键值对映射的方式进行存储 ,key在Map里面是唯一的但是value

可以重复,一个key对应一个value。HashMap采用哈希表的存储结构所以里面的数据是无序但是

唯一的。(实现唯一的方式就是重写 Hashcode和equals方法)TreeMap采用的是二叉树的存储方式,

里面的数据是唯一而且有序的,一般是按升序的方式排列 (要实现comparable接口并且重写

compareTo的方法用来实现它的排序).
14.2面试题:Map和Collection的区别

(1)存储结构不一样:

<1>Collection<E>,单例集合,只能存储一种引用数据类型

<2>Map<K,V>,双例集合,可以存储多个引用数据类型

(2)遍历方式不同

<1>Collection:迭代器遍历---最终使用的是增强for

<2>Map<K,V>: 通用的方式:将所有K获取到,通过键找值

(3)存在一定的关系

Collection里面Set子实现类都依赖于Map实现.
14.3Map基本功能

(1)V put(K key,V value):

添加键值对元素,返回键对应的值,通过方法的返回值是为null,判断键是否是第一次添加

(2)void clear() 暴力删除,将Map清空

(3)V remove(Object key):删除指定的键,返回被删除的键对应的值

(4)boolean containsKey(Object key):是否包含指定的键

(5)boolean containsValue(Object value):是否包含指定的值

(6)int size():获取Map的键值对个数(元素)

(7)Set<K> keySet():获取所有的键的集合

(8)V get(Object key):通过键获取值

(9)Collection<V> values():获取Map中所有的值

(10)Set<Map.Entry<K,V>> entrySet():获取Map集合中的键值对对象
14.4Map集合两种遍历方式

HashMap

    Map<String,String> map = new HashMap<>() ;  创建Map集合
    map.put("杨过","小龙女") ;  添加键值对元素
    map.put("郭靖","黄蓉") ;
    Set<String> set = map.keySet();  获取所有的键的集合
    for(String key :set){
        String value = map.get(key);  通过键获取值
        System.out.println(key+"="+value) ;
    }

    Set<Map.Entry<String, String>> entrySet = map.entrySet();  获取所有的键值对对象
    for(Map.Entry<String, String> en:entrySet){
        String key = en.getKey() ;  K getKey() 键值对对象获取键
        String value = en.getValue() ;  V getValue() 键值对对象获取值
        System.out.println(key+"="+value) ;
    }

(2)嵌套遍历

    HashMap<String,ArrayList<Student>> map = new HashMap<>() ;
    Set<String> set = map.keySet();
    for(String key :set){
        System.out.println(key);
        ArrayList<Student> value = map.get(key);
        for(Student s:value){
            System.out.println("\t\t"+s.getName()+"\t"+s.getAge());
            }
        }
    }

(3)TreeMap<K,V>:针对元素(键)自然排序或者比较器排序,取决于构造方法

<1>public TreeMap():自然排序
<2>public TreeMap(Comparator<? super K> comparator):比较器排序

    //public TreeMap(Comparator<? super K> comparator):比较器排序
    TreeMap<Student,String> tm = new TreeMap<>(new Comparator<Student>() {
        @Override
        public int compare(Student s1, Student s2) {
        int num = s1.getAge() -s2.getAge() ;   学生的年龄从小到大
        int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ;
        return num2 ;
        }
    }) ;

15.Collections类

Collections类:针对集合操作的工具类
特有功能

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

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

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

<4>public static <T> void sort(List<T> list,Comparator<? super T> c):针对List集合进行比较器排序

<5>public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key):

在集合中查询key元素第一次出现索引值 (集合有序!----List<Integer>)

<6>public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T>

coll):  获取集合中最大值和最小值元素

<7>public static <T> List<T> synchronizedList(List<T> list) :和多线程结合使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值