Java面向对象进阶-Collection集合,数据结构,泛型

目录

一.集合概述

二.Collection集合体系的特点

三.Collection集合常用API

四.Collection集合的遍历方式

五.Collection集合存储自定义类型的对象

六.常见结构数据

七.List系列结合

八.补充知识:集合的并发修改异常问题

九.补充知识:泛型输入


一.集合概述

 ​​​​

 

 

二.Collection集合体系的特点

package com.wjh.d1_collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

/*
    目标:明确Collection集合体系的特点
 */
public class CollectionDemo1 {
    public static void main(String[] args) {
        //有序 可重复 有索引
        ArrayList list = new ArrayList();

        Collection list2 = new ArrayList(); //多态
        list2.add("Java");
        list2.add("Java");
        list2.add("MyBatis");
        list2.add(23);
        list2.add(23);
        list2.add(false);
        list2.add(false);
        System.out.println(list2);
        //[Java, Java, MyBatis, 23, 23, false, false]

        //无序 不重复 无索引
        Collection list1 = new HashSet();
        list1.add("Java");
        list1.add("Java");
        list1.add("MyBatis");
        list1.add(23);
        list1.add(23);
        list1.add(false);
        list1.add(false);
        System.out.println(list1);
        //[Java, false, 23, MyBatis]

        
    }
}

[Java, Java, MyBatis, 23, 23, false, false]
[Java, false, 23, MyBatis]

进程已结束,退出代码为 0

 

System.out.println("-----------------");
                    // 用泛型约束集合的类型,但是只能用引用类型
        Collection<String> list3 = new ArrayList();
        //JDK 7 开始之后后面的类型声明可以不写 
        
        list3.add("Java");
        //list3.add(23);
        list3.add("昨天");
        
        //集合 泛型 不支持基本数据类型,只能用引用数据类型
        
        System.out.println("-----------------");
                    // 用泛型约束集合的类型,但是只能用引用类型
        Collection<String> list3 = new ArrayList();
        //JDK 7 开始之后后面的类型声明可以不写 
        
        list3.add("Java");
        //list3.add(23);
        list3.add("昨天");
        
        //集合 泛型 不支持基本数据类型,只能用引用数据类型
        
        

三.Collection集合常用API

package com.wjh.d2_collectionApi;
/*
        -public Object[] toArray(); 把集合中的元素存储到数组中.
    小结:
        记住以上API
 */

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class CollectionApi {
    public static void main(String[] args) {
        //HashSet:添加的元素是无序 不重复 无索引
        Collection<String> list =new ArrayList<>();
        //1.添加元素 添加成功返回true
        list.add("Java");
        list.add("MySql");
        list.add("HTML");
        list.add("Java");
        list.add("昨天");
        System.out.println(list);   //[Java, MySql, HTML, Java, 昨天]

        //2.清空集合的元素
        //list.clear();     // []
        System.out.println(list);

        //3.判断集合是否为空 是空返回true 反之亦然.
        System.out.println(list.isEmpty());

        //4.获取集合的大小
        System.out.println(list.size());

        //5.判断集合是否包含某个元素
        list.contains("Java");  //true
        list.contains("java");  //false : 精准匹配
        list.contains("昨天");  //true

        //6.删除某个元素:如果有多个元素默认删除前面的第一个元素
        System.out.println(list.remove("java"));    //false -> false原因:集合中没有 "java"元素
        System.out.println(list);
        System.out.println(list.remove("Java"));    //true -> 只会删除第一个元素
        System.out.println(list);

        //7.把集合转换成数组[Java, 独孤求败, HTML, MyBatis]
        Object[] arr = list.toArray();  //Object兼容一切数据
        System.out.println("数组:" + Arrays.toString(arr));

        System.out.println("------------拓展-----------------");
        Collection<String> c1 =new ArrayList<>();
        c1.add("Java1");
        c1.add("Java2");

        Collection<String> c2 =new ArrayList<>();
        c2.add("公主");
        c2.add("素素");

        //addAll把c2集合的元素全部倒入到c1中去
        c1.addAll(c2);
        System.out.println(c1.addAll(c2));  //true

        System.out.println(c1); //[Java1, Java2, 公主, 素素, 公主, 素素]
        System.out.println(c2); //[公主, 素素]
    }
}

[Java, MySql, HTML, Java, 昨天]
[Java, MySql, HTML, Java, 昨天]
false
5
false
[Java, MySql, HTML, Java, 昨天]
true
[MySql, HTML, Java, 昨天]
数组:[MySql, HTML, Java, 昨天]
------------拓展-----------------
true
[Java1, Java2, 公主, 素素, 公主, 素素]
[公主, 素素]

进程已结束,退出代码为 0

四.Collection集合的遍历方式

1.方式一:迭代器

 

package com.wjh.d3_collection_traversal;
/*


        2.定义一个while循环,问一次取一次
          通过it.hasNext()询问是否有下一个元素,有就通过
          it.Next()取出下一个元素.
    小结:
        记住代码.
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionDemo1 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("小明");
        list.add("小亮");
        list.add("小红");
        list.add("小嘉");
        list.add("小帅");
        System.out.println(list);


        //1.得到当前集合的迭代器对象.
        Iterator<String> it = list.iterator();
//        String ele = it.next();
//        System.out.println(ele);        //小明
//        System.out.println(it.next());  //小亮
//        System.out.println(it.next());  //小红
//        System.out.println(it.next());  //小嘉
//        System.out.println(it.next());  //小帅
//
//        //System.out.println(it.next());  //越界

        //2.定义while循环
        while(it.hasNext()){
            String ele = it.next();
            System.out.println(ele);
        }

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

    }
}

[小明, 小亮, 小红, 小嘉, 小帅]
小明
小亮
小红
小嘉
小帅
----------------------

进程已结束,退出代码为 0

2.方式二:foreach/增强for循环

增强for循环

        增强for循环:既可以遍历集合也可以遍历数组

        他是JDK5出现之后,其内部原理是一个Iterator迭代器,遍历集合相当于是迭代器的简化写法.

        实现Iterable接口的类才可以使用迭代器和增强for,Collection接口已经实现了Iterable接口.

格式:

for(元素数据类型 变量名 : 数组或者Collection集合){
    //在此处使用变量即可,该变量就是元素.
}

package com.wjh.d3_collection_traversal;

import java.util.ArrayList;
import java.util.Collection;

public class CollectionDemo2 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("小明");
        list.add("小红");
        list.add("小嘉");
        list.add("小航");
        System.out.println(list);
        //[小明, 小红, 小嘉, 小航]
        //ele

        for (String ele : list){
            System.out.println(ele);
        }

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

        double[] scores = {100, 99.5, 88, 85.5, 59.5};

        for (double score : scores) {
            System.out.println(score);
        }
    }
}

[小明, 小红, 小嘉, 小航]
小明
小红
小嘉
小航
--------------------
100.0
99.5
88.0
85.5
59.5

进程已结束,退出代码为 0

double[] scores = {100, 99.5, 88, 85.5, 59.5};

        for (double score : scores) {
            System.out.println(score);
            if (score == 59.5){
                score = 100;    //修改无异议,不会影响数组和集合原本的值
            }
        }
        System.out.println(Arrays.toString(scores));    //[100.0, 99.5, 88.0, 85.5, 59.5]

3.方式三:lambda表达式

package com.wjh.d3_collection_traversal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;

public class CollectionDemo3 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("小明");
        list.add("小红");
        list.add("小嘉");
        list.add("小航");
        System.out.println(list);
        //[小明, 小红, 小嘉, 小航]
        //ele

        System.out.println("---------------");
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        System.out.println("-------代码简化-----");

        list.forEach(s ->  {
            System.out.println(s);
        });

        System.out.println("--------最终简化-------");

        list.forEach(System.out::println);

    }


}

[小明, 小红, 小嘉, 小航]
---------------
小明
小红
小嘉
小航
-------代码简化-----
小明
小红
小嘉
小航
--------最终简化-------
小明
小红
小嘉
小航

进程已结束,退出代码为 0
 

五.Collection集合存储自定义类型的对象

package com.wjh.d4_collection_object;

import java.util.ArrayList;
import java.util.Collection;

public class TestDemo {
    public static void main(String[] args) {
        //定义一个电影类
        //2.定义一个集合对象存储3部电影对象
        Collection<Movie> movies = new ArrayList<>();
        movies.add(new Movie("<<流浪地球>>", 9.6, "1,2,3"));
        movies.add(new Movie("<<地球>>", 9.9, "4,6,7"));
        movies.add(new Movie("<<流浪>>", 9.3, "8,5,9"));

        //3.遍历集合容器中的每个电影独象
        for (Movie movie2 : movies){
            System.out.println("电影名:" + movie2.getName() + "评分:" + movie2.getScore() + "主演:" + movie2.getActor());
        }

    }
}

电影名:<<流浪地球>>评分:9.6主演:1,2,3
电影名:<<地球>>评分:9.9主演:4,6,7
电影名:<<流浪>>评分:9.3主演:8,5,9

进程已结束,退出代码为 0

 

六.常见结构数据

1.数组结构概述, 栈, 队列

 

 

 

 

 

2.数组

 数组是一种查询快,增删慢的模型.

3.链表

 

 

 

4.二叉树,二叉查找数

 

 

 

5.平衡二叉树

 

 

 

 

 

 

 

 

 

6.红黑树 

 

 

 

 

 

 

 

 

 

 

 

 

 

七.List系列结合

1.List集合特点,特有API

 

package com.wjh.d5_collection_list;

import java.util.ArrayList;
import java.util.List;

public class ListDemo1 {
    public static void main(String[] args) {
        //1.创建一个ArrayList集合对象
        //List:有序,可重读,有索引
        List<String> list = new ArrayList<>();      //一条经典代码诞生了!
        list.add("Java");
        list.add("Java");
        list.add("MySql");
        list.add("MySql");
        System.out.println(list);   //[Java, Java, MySql, MySql]

        //2.在某个索引位置上插入元素
        list.add(2, "JavaScript");
        System.out.println(list);   //[Java, Java, MySql, MySql]

        //3.根据索引删除元素,
        //System.out.println(list.remove(2));// 返回被删除的元素    //MySql
        list.remove(2);
        System.out.println(list);   //[Java, Java, JavaScript, MySql, MySql]

        //4.根据索引获取元素:public E get(int index):返回集合中指定位置的元素
        System.out.println(list.get(2));
        System.out.println(list);   //[Java, Java, MySql, MySql]

        //5.修改索引位置处的元素:public E set(int index, E element)
        //System.out.println(list.set(2, "Python"));  //返回修改前的数据
        list.set(2, "Python");
        System.out.println(list);   //[Java, Java, Python, MySql]

        list.clear();
        System.out.println(list); //[]
    }
}

[Java, Java, MySql, MySql]
[Java, Java, JavaScript, MySql, MySql]
[Java, Java, MySql, MySql]
MySql
[Java, Java, MySql, MySql]
[Java, Java, Python, MySql]
[]

进程已结束,退出代码为 0

2.List集合遍历方式小结

package com.wjh.d5_collection_list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ListDemo2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java1");
        list.add("Java2");
        list.add("Java3");

        System.out.println("------------------");
        //(1)for循环
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }


        System.out.println("------------------");
        //(2)迭代器
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

        System.out.println("------------------");
        //(3)forEach
        for (String list2 : list){
            System.out.println(list2);
        }

        System.out.println("------------------");
        //(4)Lambda表达式(JDK1.8之后的)
        list.forEach(s -> {
            System.out.println(s);
        });


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

------------------
Java1
Java2
Java3
------------------
Java1
Java2
Java3
------------------
Java1
Java2
Java3
------------------
Java1
Java2
Java3
------------------
[Java1, Java2, Java3]

进程已结束,退出代码为 0

3.ArrayList集合的底层原理

 

4.LinkedList集合的底层原理

package com.wjh.d5_collection_list;

/*
    如果查询多,增删少用ArrayList集合.(用的最多)
    如果查询少,而增删首尾较多用LinkedList集合.
 */

import java.util.LinkedList;

public class ListDemo3 {
    public static void main(String[] args) {
        //LinkedList可以完成队列结构,和栈结构(双链表)
        // 栈
        LinkedList<String> list = new LinkedList<>();   //想用LinkedList的独有功能不要用多态
        //  压栈 入栈
        list.addFirst("1");
        list.addFirst("2");
        list.addFirst("3");
        list.addFirst("4");
        list.addFirst("5");
        System.out.println(list);   //[5, 4, 3, 2, 1]
        //出栈 弹栈
        System.out.println(list.getFirst());    //5 ;只是取出但是没有移除
        System.out.println(list);   //[5, 4, 3, 2, 1]

        System.out.println(list.remove());   //5 ;返回取出结果,并且将getFirst移除
        System.out.println(list.remove());   //4 ;返回取出结果,并且将getFirst移除
        System.out.println(list.remove());   //3 ;返回取出结果,并且将getFirst移除
        System.out.println(list);   //上面执行三次移除首位元素 最终结果:[2, 1]


        System.out.println("-------------------");
        // 队列
        LinkedList<String> queue = new LinkedList<>();
        //入队
        queue.addLast("1");
        queue.addLast("2");
        queue.addLast("3");
        queue.addLast("4");
        queue.addLast("5");
        System.out.println(queue);  //[1, 2, 3, 4, 5]

        //出队
        System.out.println(queue.getLast());    //5;只是取出但是没有移除
        System.out.println(queue);  //[1, 2, 3, 4, 5]

        System.out.println(queue.removeFirst()); //1 ;返回取出结果,并且将getFirst移除
        System.out.println(queue.removeFirst()); //2 ;返回取出结果,并且将getFirst移除
        System.out.println(queue.removeFirst()); //3 ;返回取出结果,并且将getFirst移除
        System.out.println(queue);  //[4, 5]

        //扩展
        queue.push("s");    //压栈:与addFirst一样
        System.out.println(queue);  //[s, 4, 5]

        System.out.println(queue.pop());    //弹栈:与removeFirst一样
        System.out.println(queue);  //[4, 5]

    }
}

[5, 4, 3, 2, 1]
5
[5, 4, 3, 2, 1]
5
4
3
[2, 1]
-------------------
[1, 2, 3, 4, 5]
5
[1, 2, 3, 4, 5]
1
2
3
[4, 5]
[s, 4, 5]
s
[4, 5]

进程已结束,退出代码为 0

八.补充知识:集合的并发修改异常问题

 

package com.wjh.d6_collection_update_delete;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
    目标:研究集合遍历并删除元素可能会出现的问题 -> 并发修改异常问题.
 */
public class Test {
    public static void main(String[] args) {
        //1.准备数据
        List<String> list = new ArrayList<>();
        list.add("唱");
        list.add("唱");
        list.add("跳");
        list.add("rap");
        list.add("rap");
        list.add("篮球");
        list.add("music");
        list.add("music");
        System.out.println(list);   //[唱, 跳, rap, rap, 篮球, music]

        //[唱, 跳, rap, rap, 篮球, music]
        //ik

        //需求:删除全部的rap信息
        //a.迭代器遍历删除
        Iterator<String> it = list.iterator();
        //输入list.iterator 按下ctrl+alt+V 自动补全代码
        while(it.hasNext()){
            String ele = it.next();
            if(ele.equals("rap")){
                //list.remove("rap"); 报错;删除后跳位也同时执行导致删除异常
                it.remove();    //删除当前所在元素,并且不会跳位(后移)
                //使用迭代器删除当前位置的元素,保证不后移,能够成功遍历到全部元素!
            }
        }
        System.out.println(list);

        //b.forEach遍历删除(会出现bug)
//        for(String s : list){
//            if(s.equals("music")){
//                //list.remove(s);   //报错!并发修改异常:同时遍历同时删除
//            }
//        }

        //c.lambda表达式(会出现bug)
//        list.forEach(s -> {
//            if(s.equals("music")){
//                //list.remove(s); //报错! :并发修改异常:同时遍历同时删除
//            }
//        });
//        System.out.println(list);

        //d.for循环(不出异常,但是数据有误,会漏删)
//        for (int i = 0; i < list.size(); i++) {
//            String ele = list.get(i);
//            if (ele.equals("music")){
//                list.remove(ele);
//            }
//        }
//        System.out.println(list);

        //解决方案: 倒着删!
        //[唱, 跳, rap, rap, 篮球, music, music]
        //          i
        for (int i = list.size() - 1; i >= 0; i--) {
            String ele = list.get(i);
            if (ele.equals("music")){
                list.remove("music");
            }
        }
        System.out.println(list);

        //解决方案2: 增加退格操作
        for (int i = 0; i < list.size(); i++) {
            String ele = list.get(i);
            if (ele.equals("唱")){
                list.remove(ele);
                i--;
            }
        }
        System.out.println(list);


    }

}

[唱, 唱, 跳, rap, rap, 篮球, music, music]
[唱, 唱, 跳, 篮球, music, music]
[唱, 唱, 跳, 篮球]
[跳, 篮球]

进程已结束,退出代码为 0
 

九.补充知识:泛型输入

1.泛型的概述和优势

package com.wjh.d7_genericity;
/*
    目标:泛型的概述

    什么是泛型?
        泛型是一个标签:<数据类型>
        泛型在编译阶段只能操作某种数据类型.

     注意:
        JDK1.7开始后后面的泛型声明可以省略不写

     小结:
        泛型是一个标签.
        泛型在编译阶段只能操作某种数据类型.
        泛型只支持引用数据类型,不支持基本数据类型
        Object -> 所有数据类型
 */

import java.util.ArrayList;
import java.util.List;

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

        //后面需要强转数据类型,太麻烦,所以可以用泛型先约束
//        List list1 = new ArrayList<>();
//        list1.add("Java1");
//        list1.add(88);
//        list1.add(true);
//        list1.add(99.5);
//
//        for (Object o : list1) {
//            String ele = o + "";
//            System.out.println(ele);
//        }

        List<String> list = new ArrayList<>();
        list.add("Java1");
        list.add("Java2");
        list.add("Java3");
        //list.add(23);
        System.out.println(list);

        System.out.println("-------Object-------");
        //存输任意元素
        List<Object> list2 = new ArrayList<>();
        list2.add("Java");
        list2.add(23);
        list2.add(98.5);
        list2.add(false);

        System.out.println(list2);


    }
}

[Java1, Java2, Java3]
-------Object-------
[Java, 23, 98.5, false]

进程已结束,退出代码为 0

2.自定义泛型类

 

 MyArrayList类:

package com.wjh.d8_genericity_class;

import java.util.ArrayList;

public class MyArrayList<E> {

    private ArrayList lists = new ArrayList();
    //包装类(换壳)
    
    public void add(E e){
        lists.add(e);
    }
    public void remove(E e){
        lists.remove(e);
    }

    @Override
    public String toString() {
        return lists.toString();
    }
}

测试类:

package com.wjh.d8_genericity_class;

public class Test {
    public static void main(String[] args) {
        //需求:模拟ArrayList定义一个MyArrayList,关注泛型设计
        MyArrayList<String> list = new MyArrayList<String>();
        list.add("Java");
        list.add("C++");
        list.add("Java");
        list.remove("C++");
        System.out.println(list);

        MyArrayList<Integer> list1 = new MyArrayList<Integer>();
        list1.add(23);
        list1.add(59);
        list1.add(98);
        list1.add(100);
        list1.remove(59);
        System.out.println(list1);
    }
}

[Java, Java]
[23, 98, 100]

进程已结束,退出代码为 0

3.自定义泛型方法

package com.wjh.d9_genericity_method;
/*
        定义了泛型的方法就是泛型方法

    泛型方法的定义格式:
        修饰符 <泛型变量> 返回值类型 方法名称(形参列表){

        }
        注意:方法中定义了什么泛型变量,后面就只能用什么泛型变量
        泛型类的核心思想:是把泛型变量的地方全部替换成传输的真实数据类型.

        需求:给你一个任何数据类型,都能返回他的内容. Array.toString(数组)的功能!

        小结:
            泛型放大可以更灵活地接受数据,可以做通用技术!
 */

public class GenericDemo {
    public static void main(String[] args) {
        String[] names = {"唱", "跳", "rap", "篮球"};
        printArray(names);

        Integer[] ages = {23, 18, 30};
        printArray(ages);
    }

    /**
     *
     * @param arr  数组变量
     * @param <T> 自定义泛型类型T
     */
    public static <T> void printArray(T[] arr){

        if (arr != null){
        StringBuilder sb = new StringBuilder("[");
            for (int i = 0 ; i < arr.length ;i++) {
                sb.append(arr[i]).append(i == arr.length - 1 ? "" : ",");
            }
            sb.append("]");
            System.out.println(sb);
        }else{
            System.out.println(arr);
        }

    }
}

[唱,跳,rap,篮球]
[23,18,30]

进程已结束,退出代码为 0

4.自定义泛型接口

 Date接口:

package com.wjh.d10_enericity_interface;

public interface Date<T> {
    void add(T t);
    void delete(int id);
    void update(T t);
    void queryById(int id);

}

 测试类:

package com.wjh.d10_enericity_interface;

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

Student类:

package com.wjh.d10_enericity_interface;

public class Student {

}

StudentDate类:        重写Date接口方法

package com.wjh.d10_enericity_interface;

public class StudentDate implements Date<Student>{
    @Override
    public void add(Student student) {
        
    }

    @Override
    public void delete(int id) {

    }

    @Override
    public void update(Student student) {

    }

    @Override
    public void queryById(int id) {

    }
}

Teacher类:

package com.wjh.d10_enericity_interface;

public class Teacher {

}

TeacherDate类:        重写Date接口方法

ackage com.wjh.d10_enericity_interface;

public class TeacherDate implements Date<Teacher>{

    @Override
    public void add(Teacher teacher) {
        
    }

    @Override
    public void delete(int id) {

    }

    @Override
    public void update(Teacher teacher) {

    }

    @Override
    public void queryById(int id) {

    }
}

5.泛型通配符,上下限

package com.wjh.d11_genericity_car;
/*
    小结:
        通配符: ?
        ? 可以在"使用泛型"的时候代表一切类型.
 */

import java.util.ArrayList;

public class GenericDemo {
    public static void main(String[] args) {
        ArrayList<Car> cars = new ArrayList<>();
        cars.add(new BENZ());
        cars.add(new BMW());
        go(cars);

//        ArrayList<Dog> dogs = new ArrayList<>();
//        dogs.add(new Dog());
//        dogs.add(new Dog());
//        dogs.add(new Dog());
//        go(dogs);

    }
    
    /*
        所有类型都能进来比赛
     */
    //public static void go(ArrayList<?> cars){  } // ? -> 代表一切类型

    /**
     * 所有车进来比赛(<? extends Car>只有继承了Car的子类才能进来比赛)
     * @param cars
     */
    public static void go(ArrayList<? extends Car> cars){   // ? -> 代表一切类型
    
    }
}



    class BENZ extends Car{

    }

    class BMW extends Car{

    }
    
    //其他类
    class Dog{
    
    }

    //Car父类
    class Car {

    }
    
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员希西子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值