Collection集合总结

Collection是根部接口,具体看下图:

1、List

(1)、添加、获取元素

package List;

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

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/13 22:51
 *
 * List集合根据角标获取元素
 */
public class List1 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add(1);
        System.out.println(list);
        //根据角标添加元素
        //index必须小于等于list的size
        list.add(1,"myxq");
        System.out.println(list);

        //获取制定角标的元素
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}

上面代码中的list.add(1);这里调用的add方法会在内部自动装箱,当我们打开该文件的字节码可以看到:

本是基本数据类型的1在内部被自动转换成了Integer的包装类型,其他基本数据类型也是一样会被转换相应的包装类型。
(2)、删除元素(解决删除元素的并发异常)

package List;

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

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/13 22:58
 *
 * List集合解决删除元素的并发异常
 */
public class List2 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");

        //java.util.ConcurrentModificationException
        //并发修改异常
        //在迭代集合的过程的当中,是不允许直接修改集合的结构的
        //删除时可以使用迭代器之中的删除
        //遍历集合,如果元素等于2,则删除2

        // 在获取迭代器时modCount == expectedModCount
        // modCount:集合修改的次数
        // expectedModCount:迭代器当中记录集合修改的次数
        // 只要修改的次数不相等
        // modCount != expectedModCount
        // throw new ConcurrentModificationException();
        // 所以list.remove("2")执行时modCount改变,就和expectedModCount不等
        // 而迭代器中的remove会执行expectedModCount = modCount;

        //1.遍历集合
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            //2.取出对应元素
            String str = (String) iterator.next();
            //3.判断元素是否等于2
            if (str.equals("2")){
                //4.等于2就把该元素删除
                //list.remove("2");
                iterator.remove();  //删除当前正在迭代集合的元素(正在遍历元素next)
                list.add("myxq");  // Increments modCount!!导致modCount != expectedModCount
            }
        }
        System.out.println(list);
    }
}

(3)、添加元素(解决添加元素的并发异常)
在上面的删除元素中,我们可以通过迭代器的删除来解决删除元素导致的modCount != expectedModCount问题,但是迭代器中没有add方法,所以这时我们可以使用List自己的迭代器ListIterator:

package List;

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

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/13 23:22
 *
 * List集合解决添加元素的并发异常
 */
public class List3 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");

        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            String str = (String) iterator.next();
            if (str.equals("2")){
                //list.add("myxq");  // Increments modCount!!导致modCount != expectedModCount
            }
        }

        //在List中有自己的迭代器
        ListIterator listIterator = list.listIterator();
        System.out.println(listIterator);//java.util.ArrayList$ListItr@4554617c
        while (listIterator.hasNext()){
            String lstr = (String) listIterator.next();
            if (lstr.equals("2")){
                listIterator.add("myXq");
            }
        }
        System.out.println(list);//[1, 2, myXq, 3, 4]
    }
}

ListIterator和迭代器的用法差不多,如下:

package List;

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

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/13 23:31
 *
 * ListIterator迭代器方法
 */
public class ListIterator {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");

        java.util.ListIterator listIterator = list.listIterator();
        while (listIterator.hasNext()){
            System.out.print(listIterator.next()+"\t");
        }
        System.out.println();
        System.out.println(list);

        while (listIterator.hasPrevious()){
            System.out.println("preIndex = " + listIterator.previousIndex());
            System.out.println(listIterator.previous());
        }
        //上面循环输出的最终结果如下
        /**
         * preIndex = 3
           4
           preIndex = 2
           3
           preIndex = 1
           2
           preIndex = 0
           1
         */
    }
}

本来此处是一个小例子,但是在这个例子之前还得看看泛型的概念
当我们使用List的get方法时,取出来的全是Object对象,这会造成一定的麻烦,因为不同类型的对象时无法比较的,而且有些方法也无法使用,例如:当我们存储的是字符串时,想要使用字符串的某些方法,我们还得强转回来,所以这就引出了泛型的概念,给集合一个约束,约定只能存储什么类型的数据

泛型:广泛通用的类型(一开始不确定什么类型,在使用的时候才能确定是什么类型),换句话说就是代码模块中不确定自己是什么类型的,只有在谁调用它调用他的时候才来指明这个类型
但是泛型的本质还是Object,他是一个语法糖(此处就不解释语法糖了),只是在内部被强转了,具体可见以下的代码及其字节码

package List;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 13:50
 */

//T:type  E:element  k:key可以自定义
class Point2<T>{
    //1、可以使字符串类型
    //2、Integer
    //3、Double

    //定义成泛型
    T x;
    T y;

    public T getY() {
        return y;
    }
}
public class GenericType2 {
    public static void main(String[] args) {
        /**
         *
         * 1、在开始定义类的时候,就留一个插口
         * 2、在创建对象的时候,再去插入对应的类型
         */

        //创建对象时要指明泛型时什么类型
        //如果没有指明,那就是Object类型
        Point2<String> point2 = new Point2<String>();
        point2.x = "10";
        point2.y = "20";
        System.out.println(point2.getY());
    }
}


如上图中代码所示,语句System.out.println(point2.getY());本质上是System.out.println((String)point2.getY());也就是说输出的其实还是Object,只是在内部被强转成了String类型。
泛型类以及泛型方法的使用

package List;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 14:41
 */

class Gtest<T>{
    T name;

    public T getName() {
        return name;
    }
}
class Gstudent{
    //泛型方法
    <T> void test(T a){
        System.out.println(a.getClass());
    }

    //静态方法也可以自定义泛型
    static <E> E test2(E name){
        System.out.println(name.getClass());
        return name;
    }
}
public class GenericType3 {
    /**
     * 1、泛型类:在类上面定义的类型,在,在创建对象时要指定泛型类型
     *            泛型当中定义的泛型只能用在普通方法上
     *            不能使用在静态方法上面
     *            静态方法是直接使用类名调用的,泛型是在创建对象时才去指定类型
     * 2、自定义泛型方法:方法上面添加了泛型
     *            单独的对一个方法上面泛型
     *            方法中定义的泛型,是在使用方法时,参数传递时确定具体是什么类型
     *            所以方法想要使用泛型,必须要有参数才有意义
     */

    public static void main(String[] args) {
        Gtest<String> t = new Gtest<>();
        Gtest<String> t1 = new Gtest();

        new Gstudent().test(10);//class java.lang.Integer
        new Gstudent().test("10");//class java.lang.String
        new Gstudent().test2(true);//class java.lang.Boolean
        String name = new Gstudent().test2("yuanZhi");
        System.out.println(name);//yuanZhi
        Boolean aBoolean = new Gstudent().test2(true);
        System.out.println(aBoolean);//true
    }
}

package List;

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

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 15:24
 */
public class GenericType4 {
    /**
     * 通配符:不知道使用什么类型来接收的时候,可以使用?表示未知
     *         只能用来做接收使用
     *         不能用来添加
     * @param args
     */
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        test(list);
//        test2(list);  报错,因为只能是Number或者Number的父类

//        List<String> list2 = new ArrayList<>();
//        test(list2);    String并没有继承Number,所以在此处报错

//        List<?> list3 = new ArrayList<>();
//        list3.add("a");  报错,只能接收,不能添加
    }

    static void test(List<? extends Number> list){

    }
    static void test2(List<? super Number> list){

    }
}

好了,泛型介绍完了,下面就来讲一个List的学科、班级、学生的小例子:

package List;

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

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 15:41
 */
class Person{
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
public class ListExample {
    public static void main(String[] args) {
        /**
         * 学科  学科中有很多班级
         * 班级中又有很多学生
         */
        Person p1 = new Person("zs");
        Person p2 = new Person("ls");
        List<Person> c1 = new ArrayList<>();//班级1
        c1.add(p1);
        c1.add(p2);

        Person p3 = new Person("zs1");
        Person p4 = new Person("ls2");
        List<Person> c2 = new ArrayList<>();//班级2
        c2.add(p1);
        c2.add(p2);

        List<List<Person>> m = new ArrayList<>();//学科(集合中存集合)
        m.add(c1);
        m.add(c2);

        //打印所有班级中的学生姓名
        for (List<Person> list:m) {
            for (Person p:list) {
                System.out.println(p.getName());
            }
        }
    }
}

ArrayList

上面List有的用法,ArrayList都有,所以这里不重复介绍


去除集合中的重复元素

package List;

import java.util.ArrayList;
import java.util.ListIterator;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/14 19:34
 *
 * 去除集合当中重复的元素
 */
public class ArrayList1 {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add("a");
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");
        System.out.println(arrayList);//[a, a, b, b, c, d]
        //想要的是[a,b,c,d]

        ArrayList newList = getSingleEle(arrayList);
        System.out.println(newList);//[a, b, c, d]
    }

    private static ArrayList getSingleEle(ArrayList arrayList) {
        //1、创建一个空集合
        ArrayList newList = new ArrayList();
        //2、依次取出元素
        ListIterator listIterator = arrayList.listIterator();
        while (listIterator.hasNext()){
            //3、每取出一个元素,先判断新集合中是否已经包含了元素
            Object object =listIterator.next();
            //4、如果包含,就不添加,不包含菜添加到新集合
            if(!newList.contains(object)){
                newList.add(object);
            }
        }
        return newList;
    }
}

去除自定义对象的重复元素

package List;

import java.util.ArrayList;
import java.util.ListIterator;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/14 20:23
 *
 * 去除自定义对象重复元素
 */
class Student{
    String name;
    int age;

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

    //作对象的对比,不想让其比较地址,就得重写equals
    @Override
    public boolean equals(Object obj) {
        Student stu = (Student) obj;
        return this.name.equals(stu.name) && this.age == stu.age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class ArrayList2 {
    private static ArrayList getSingleEle(ArrayList arrayList) {
        //1、创建一个空集合
        ArrayList newList = new ArrayList();
        //2、依次取出元素
        ListIterator listIterator = arrayList.listIterator();
        while (listIterator.hasNext()){
            //3、每取出一个元素,先判断新集合中是否已经包含了元素
            Object object =listIterator.next();
            //4、如果包含,就不添加,不包含菜添加到新集合
            if(!newList.contains(object)){//contains判断有没有某元素(equals)->Object -> 地址
                //没有重写equals,所以比的就是地址,当前的object就是Student类,而Student类并没有重写equals,所以地址不同导致都不包含
                //所以在Student中药重写equals方法
                newList.add(object);
            }
        }
        return newList;
    }
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(new Student("张三",20));
        list.add(new Student("张三",20));
        list.add(new Student("李四",21));
        System.out.println(list);//[Student{name='张三', age=20}, Student{name='张三', age=20}, Student{name='李四', age=21}]

        ArrayList newList = getSingleEle(list);
        System.out.println(newList);//[Student{name='张三', age=20}, Student{name='李四', age=21}]
    }
}

LinkedList

LinkedList的底层是基于链表的,如图:

同样List有的LinkedList也有,除此之外,还有特有的:

package List;

import java.util.ListIterator;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 10:52
 */
public class LinkedList1 {
    public static void main(String[] args) {
        java.util.LinkedList list = new java.util.LinkedList();
        list.add("a");
        list.add("b");
        list.add("c");
        System.out.println(list);
        ListIterator iterator = list.listIterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //特有
        //往第一个位置添加元素
        list.addFirst("mySql");//[mySql, a, b, c]
        list.addFirst("1");//[1, mySql, a, b, c]
        System.out.println(list);
        //在集合的最后添加元素
        list.addLast("yuanZhi");
        System.out.println(list);//[1, mySql, a, b, c, yuanZhi]
        //移除第一个元素
        list.removeFirst();
        System.out.println(list);//[mySql, a, b, c, yuanZhi]
        //移除最后一个
        list.removeLast();
        System.out.println(list);//[mySql, a, b, c, yuanZhi]
        //根据角标获取元素
        //LinkedList查询是比较慢的,需要经历for循环依次询问
        System.out.println(list.get(0));
    }
}

用LinkedList模拟出栈入栈

package List;

import java.util.LinkedList;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 11:06
 */

class Stack{
    LinkedList linkedList;
    Stack(){
        linkedList = new LinkedList();
    }
    //入栈:在集合最后添加一个元素
    void push(Object object){
        linkedList.addLast(object);
    }
    //出栈:把集合中最后一个元素移除
    void pop(){
        linkedList.removeLast();
    }

    @Override
    public String toString() {
        return "Stack{" +
                "linkedList=" + linkedList +
                '}';
    }
}
public class LinkedList2 {
    public static void main(String[] args) {
        Stack stack = new Stack();
        stack.push("a");
        stack.push("b");
        stack.push("c");
        System.out.println(stack);//Stack{linkedList=[a, b, c]}
        stack.pop();//Stack{linkedList=[a, b]}
        System.out.println(stack);
    }
}

Vector

底层也是基于数组,使用少,因为如果只有一个线程访问集合,一般也最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果多线程访问集合,那么最好使用Vector,因为Vector的所有方法前面都加了锁,而ArrayList没有,所以Vector是线程安全的ArrayList不是。

package List;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 11:27
 */
public class Vector {
    public static void main(String[] args) {
        java.util.Vector vector = new java.util.Vector();
        vector.add("a");
        vector.add("b");
        vector.add("c");
        System.out.println(vector);//[a, b, c]


    }
}

Set

Set中存的是无序不重复元素,并且已经覆盖了toString方法。

package Set;

import java.util.HashSet;
import java.util.Iterator;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 15:52
 */
public class Set1 {
    public static void main(String[] args) {
        //Set中存的是无序不重复的元素,并已经覆盖了toString
        HashSet<String> hs = new HashSet<>();
        boolean res1 = hs.add("a");
        boolean res2 = hs.add("a");
        hs.add("b");
        hs.add("c");
        hs.add("2");
        hs.add("1");
        System.out.println(res1);//true
        System.out.println(res2);//false
        System.out.println(hs);//[a, 1, b, 2, c]

        Iterator iterator = hs.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //只要能用迭代器的,都可用它的增强型foreach
        for (String str:hs
             ) {
            System.out.println(str);
        }
    }
}

Set存储的元素时不重复的,但是若是自定义的对象,是会重复的,所以需要我们自己重写其中的equals和hashCode方法来达到存储的是不可重复元素的目的。

package Set;

import java.util.HashSet;
import java.util.Set;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 16:01
 */

class Person{
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (name != null ? !name.equals(person.name) : person.name != null) return false;
        return age != null ? age.equals(person.age) : person.age == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (age != null ? age.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Set2 {
    public static void main(String[] args) {

        //想要在Set中自定义对象去重
        //1、重写equals
        //2、重写hashCode
        //3、自定义对象属性完全相同的话,就判定是同一个对象
        Set<Person> s = new HashSet<Person>();
        s.add(new Person("张三",20));
        s.add(new Person("张三",20));
        s.add(new Person("李四",21));
        s.add(new Person("李四",21));
        s.add(new Person("李四",21));

        System.out.println(s);//[Person{name='张三', age=20}, Person{name='李四', age=21}]
    }
}

利用Set的这一特性,可以获取1-20之间10个不重复的随机数

package Set;

import java.util.HashSet;
import java.util.Random;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 16:47
 *
 * 获取1-20之间的10个不重复的随机数
 */
public class GetRandom {
    public static void main(String[] args) {
        //1、使用random生产随机数
        Random random = new Random();
        //2、创建生成结果的集合
        HashSet<Integer> hashSet = new HashSet<>();
        //3、当生成的个数大于集合的size就不放了
        while (hashSet.size() < 10){
            //4、生成1-20之间的随机数
            int res = random.nextInt(20) + 1;
            //5、添加到集合当中
            hashSet.add(res);
        }
        System.out.println(hashSet);
    }
}

另外还可以达到字符串去重的目的

package Set;

import java.util.LinkedHashSet;
import java.util.Scanner;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 16:55
 *
 * 字符串去重
 */
public class RemoveRepeate {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String line = scanner.nextLine();//adhasjdhasjdsagdhasjh
        //1、拿到字符串中的每一个字符
        char[] arr = line.toCharArray();
        //2、取出每一个元素,添加到一个可以去重的集合中
        //为了保证输出输入顺序一致,选用LinkedHashSet
        LinkedHashSet<Character> hs = new LinkedHashSet<>();
        for (char c:arr
             ) {
            hs.add(c);
        }
        System.out.println("去重后的结果:"+hs);//去重后的结果:[a, d, h, s, j, g]
    }
}

TreeSet

TreeSet也是无序的(不会按照你添加的顺序展示),但是它会对你添加的元素进行排序,所以要保证元素的顺序时可以使用TreeSet

package Set;

import java.util.TreeSet;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 17:02
 */
public class TreeSet1 {
    public static void main(String[] args) {
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(2);
        treeSet.add(2);
        treeSet.add(7);
        treeSet.add(9);
        treeSet.add(6);
        System.out.println(treeSet);//[2, 6, 7, 9]

        TreeSet<String> treeSet2 = new TreeSet<>();
        treeSet2.add("a");
        treeSet2.add("c");
        treeSet2.add("b");
        treeSet2.add("e");
        treeSet2.add("j");
        System.out.println(treeSet2);//[a, b, c, e, j]

        //汉字根据Unicode的值
        TreeSet<String> treeSet3 = new TreeSet<>();
        treeSet3.add("远");
        treeSet3.add("志");
        System.out.println('远'+0);//36828
        System.out.println('志'+0);//24535
        System.out.println(treeSet3);//[志, 远]
    }
}

TreeSet添加元素时对你添加的元素进行排序是基于二叉树的算法,根据对其底层源码的分析,是在调用add方法时会调用一个compareTo方法,该方法会有一个返回值,若返回值为0,则只添加你添加的所有元素中的第一个元素;若是任意一正数,则都添加到集合中并且按照顺序显示;若是返回是任意一负数,则都添加到集合中,但是是按照倒序显示。

package Set;

import java.util.TreeSet;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 17:15
 */

class Person2 implements Comparable<Person2>{
    private String name;
    private Integer age;

    public Person2(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person2 o) {
        int num = this.age - o.age;
        /*if (num == 0){
            return this.name.compareTo(o.name);
        }else {
            return num;
        }*/
        return num == 0 ? this.name.compareTo(o.name) : num;
    }

    @Override
    public String toString() {
        return "Person2{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class TreeSet2 {
    public static void main(String[] args) {
        //TreeSet中存放的类型必须是同一类型,
        // 因为不是同一类型没有可比性

        //自定义的对象不能直接添加到TreeSet中
        //想要添加到TreeSet中,必须实现Comparable接口
        //重写其中的compareTo方法
        TreeSet<Person2> set = new TreeSet<>();
        set.add(new Person2("张三",20));
        set.add(new Person2("李四",21));
        set.add(new Person2("李四1",21));
        set.add(new Person2("王五",25));
        set.add(new Person2("赵六",23));
        System.out.println(set);
    }
}

另外,默认是调用对象的compareTo进行比较,如果自己传入了比较器,就会使用传入的比较器进行比较

package Set;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * @Author: yuanzhi...
 * @Date: created in  2020/1/15 19:11
 */
public class TreeSet4 {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>();
        //默认使用字母的顺序
        set.add("aaaaaaa");
        set.add("z");
        set.add("wq");
        set.add("yz");
        set.add("nb");
        System.out.println(set);//[aaaaaaa, nb, wq, yz, z]
        System.out.println("=========================分割线========================");

        //使用比较器进行比较
        //1、实现一个接口comparator
        //2、定义一个类来实现这个接口
        //3、重写它里面的方法
        TreeSet<String> set2 = new TreeSet<>(new CompareLength());
        set2.add("aaaaaaa");
        set2.add("z");
        set2.add("wq");
        set2.add("wq");
        set2.add("yz");
        set2.add("nba");
        System.out.println(set2);//[z, wq, yz, nba, aaaaaaa]
    }
}

class CompareLength implements Comparator<String>{
    /**
     *
     * @param o1 当前正在添加的对象
     * @param o2 集合中的对象
     * @return
     */
    @Override
    public int compare(String o1, String o2) {
        int length = o1.length() - o2.length();  //主要比长度
        return length == 0 ? o1.compareTo(o2) : length;  //如果长度相等再去比较内容
    }
}

有不到位的地方还请谅解
作者君总结码字不易,点个赞再走吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值