Collection集合容器基础讲解

一.简介

 

 

Collection是最基本的集合/容器接口,一个Collection代表一组Object,即Collection的元素。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。

 

 

图解

 

即:

Collection主要子接口对象

   List接口 元素可重复

  Set接口 元素不可重复

   Map接口 没有继承Collection接口,Map提供key到value的映射

 

下面对List,Map,Set。一一讲解。

 

 

 

 

 

 

二.List接口详解

 

1.List接口描述

List是有序,可重复的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,也就是说它是有顺序的,类似于Java的数组。和Set不同,List允许有相同的元素。J2SDK所提供的List容器类有ArrayList、LinkedList等。

 

 

2.List接口的实现类之ArrayList

 

<1> ArrayList描述

ArrayList其实就相当于顺式存储,它包装了一个数组 Object[],当实例化一个ArrayList时,一个数组也被实例化,当向ArrayList中添加对象时,数组的大小也相应的改变。

 

 

<2> ArrayList特点

 

(1) 快速随即访问,你可以随即访问每个元素而不用考虑性能问题,通过调用get(i)方法来访问下标为i的数组元素。

 

(2) 向其中添加对象速度慢,当你创建数组时并不能确定其容量,所以当改变这个数组时就必须在内存中做很多事情。

 

(3) 操作其中对象的速度慢,当你要向数组中任意两个元素中间添加对象时,数组需要移动所有后面的对象。

 

 

 

<3> ArrayList使用demo

代码

package com.example.mytest;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initArrayList();
    }

    public void initArrayList() {
        List<String> list = new ArrayList<String>();
        list.add(null);
        list.add("bbbb");
        list.add("bbbb");
        list.add("bbbb");
        list.add("aaaa");
        list.add("bbbb");
        list.add("cccc");
        list.add("dddd");
        list.add("dddd");
        list.add("dddd");
        list.add(null);

        Iterator<String> i = list.iterator();
        while (i.hasNext()) {
            Log.i("TAG", "Iterator遍历----:" + i.next());
        }
        Log.i("TAG", "*****************************************");

        for (int m = 0; m < list.size(); m++) {
            Log.i("TAG", "for循环----:" + list.get(m));
        }
        Log.i("TAG", "*****************************************");


        Log.i("TAG", "list长度----:" + list.size());
    }

}

 

结果

I/TAG: Iterator遍历----:null

I/TAG: Iterator遍历----:bbbb

I/TAG: Iterator遍历----:bbbb

I/TAG: Iterator遍历----:aaaa

I/TAG: Iterator遍历----:bbbb

I/TAG: Iterator遍历----:cccc

I/TAG: Iterator遍历----:dddd

I/TAG: Iterator遍历----:dddd

I/TAG: Iterator遍历----:null


I/TAG: *****************************************

I/TAG: for循环----:null

I/TAG: for循环----:bbbb

I/TAG: for循环----:bbbb

I/TAG: for循环----:aaaa

I/TAG: for循环----:bbbb

I/TAG: for循环----:cccc

I/TAG: for循环----:dddd

I/TAG: for循环----:dddd

I/TAG: for循环----:null


I/TAG: *****************************************

I/TAG: list长度----:11

也就是说ArrayList 有序(插入和输出顺序一致) 元素可重复 元素可为空 。

 

 

 

 

 

3.List接口的实现类之LinkedList

 

<1> LinkedList描述

LinkedList相当于链式存储,它是通过节点直接彼此连接来实现的。每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可,当删除记录时也一样。

 

 

 

<2> LinkedList有特点

 

(1) 操作其中对象的速度快,只需要改变连接,新的节点可以在内存中的任何地方。

 

(2) 不能随即访问,虽然存在get()方法,但是这个方法是通过遍历接点来定位的,所以速度慢。

 

 

 

<3> Linkedlist使用demo

代码

package com.example.mytest;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initLinkedList();
    }

    public void initLinkedList() {
        List<String> list = new LinkedList<String>();
        list.add(null);
        list.add("bbbb");
        list.add("bbbb");
        list.add("bbbb");
        list.add("aaaa");
        list.add("bbbb");
        list.add("cccc");
        list.add("dddd");
        list.add("dddd");
        list.add("dddd");
        list.add(null);

        Iterator<String> i = list.iterator();
        while (i.hasNext()) {
            Log.i("TAG", "Iterator遍历----:" + i.next());
        }
        Log.i("TAG", "*****************************************");

        for (int m = 0; m < list.size(); m++) {
            Log.i("TAG", "for循环----:" + list.get(m));
        }
        Log.i("TAG", "*****************************************");


        Log.i("TAG", "list长度----:" + list.size());
    }

}

 

结果

I/TAG: Iterator遍历----:null

I/TAG: Iterator遍历----:bbbb

I/TAG: Iterator遍历----:bbbb

I/TAG: Iterator遍历----:aaaa

I/TAG: Iterator遍历----:bbbb

I/TAG: Iterator遍历----:cccc

I/TAG: Iterator遍历----:dddd

I/TAG: Iterator遍历----:dddd

I/TAG: Iterator遍历----:null


I/TAG: *****************************************

I/TAG: for循环----:null

I/TAG: for循环----:bbbb

I/TAG: for循环----:bbbb

I/TAG: for循环----:aaaa

I/TAG: for循环----:bbbb

I/TAG: for循环----:cccc

I/TAG: for循环----:dddd

I/TAG: for循环----:dddd

I/TAG: for循环----:null


I/TAG: *****************************************

I/TAG: list长度----:11

也就是说LinkedList 有序(插入和输出顺序一致) 元素可重复 元素可为空 。

 

以上可以看出ArrayListLinkedList用法完全一样,只是底层实现不一样。

 

 

 

 

 

 

 

三.Set接口详解

 

 

1.Set描述

Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。

 

 

 

 

2.Set接口实现类之HashSet

 

<1> HashSet描述

此类实现 Set接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。

 

 

 

<2> HashSet使用demo

 

代码

package com.example.test;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initArrayList();
    }

    public void initArrayList() {
        HashSet<String> hs = new HashSet<String>();
        hs.add(null);
        hs.add("ffff");
        hs.add("aaaa");
        hs.add("aaaa");
        hs.add("bbbb");
        hs.add("bbbb");
        hs.add("cccc");
        hs.add("cccc");
        hs.add("dddd");
        hs.add(null);

        Iterator<String> i = hs.iterator();
        while (i.hasNext()) {
            Log.i("TAG", i.next() + "");
        }
    }

}

 

结果

I/TAG: null

I/TAG: aaaa

I/TAG: bbbb

I/TAG: cccc

I/TAG: dddd

I/TAG: ffff

也就是说HashSet 无序(插入和输出顺序不一致) 元素不可重复 元素可为空 。

 

 

 

 

3.Set接口实现类之TreeSet

 

<1> TreeSet描述

此类实现Set接口,由二叉树实现的,Treeset中的数据是自动排好序的不允许放入null值

 

 

 

<2> TreeSet使用demo

 

代码

package com.example.test;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import java.util.Iterator;
import java.util.TreeSet;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initArrayList();
    }

    public void initArrayList() {
        TreeSet<String> hs = new TreeSet<String>();
        hs.add("ffff");
        hs.add("aaaa");
        hs.add("aaaa");
        hs.add("bbbb");
        hs.add("bbbb");
        hs.add("cccc");
        hs.add("cccc");
        hs.add("dddd");

        Iterator<String> i = hs.iterator();
        while (i.hasNext()) {
            Log.i("TAG", i.next() + "");
        }
    }

}

 

结果

I/TAG: aaaa

I/TAG: bbbb

I/TAG: cccc

I/TAG: dddd

I/TAG: ffff

也就是说TreeSet 序(插入和输出顺序不一致) 元素不可重复 元素不可为空 。

 

以上可以看出HashSetTreeSet用法几乎一样(TreeSet元素不可为空),只是底层实现不一样。

 

 

 

 

 

 

四.Map接口

 

 

1.Map描述

Map没有继承Collection接口,Map接口是提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。即是一一映射,Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。

 

 

 

2.Map接口实现类之HaspMap

 

<1> HaspMap描述

添加数据使用put(key, value),取出数据使用get(key),HashMap是允许null,即null value和null key。但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。

 

 

<2> HashMap使用demo

 

代码

package com.example.test;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initArrayList();
    }

    public void initArrayList() {
        HashMap<String, String> map = new HashMap<String, String>();
        HashMap<String, String> allmap = new HashMap<String, String>();

        /**
         * put("key","value")——>“key”“values”
         */

        map.put("1", "张三");
        map.put("2", "李四");
        map.put("3", "王五");
        map.put("4", "赵六");

        /**
         * putAll(map); ——>把一个map全部放到另一个map中
         */

        allmap.putAll(map);

        /**
         * get ——>根据key获取相应的values
         */

        String str = map.get("2");
        String allstr = allmap.get("2");
        Log.i("TAG", "get ——>根据key获取相应的values----str----:" + str);
        Log.i("TAG", "get ——>根据key获取相应的values----allstr----:" + allstr);
        Log.i("TAG", "********************************************************************");

        /**
         * size——>map长度
         */

        int len = map.size();
        int alllen = allmap.size();
        Log.i("TAG", "size——>map长度----len----:" + len);
        Log.i("TAG", "size——>map长度----alllen----:" + alllen);
        Log.i("TAG", "*********************************************************************");

        /**
         * containsKey(“key”)——>map中是否包含相应的key
         */

        boolean b1 = map.containsKey("2");
        Log.i("TAG", "containsKey(“key”)——>map中是否包含相应的key----b1----:" + b1);
        Log.i("TAG", "**********************************************************************");

        /**
         * containsValue(“values”)——>map中是否包含相应的values
         */

        boolean b2 = map.containsValue("李四");
        Log.i("TAG", "containsValue(“values”)——>map中是否包含相应的values----b2----:" + b2);
        Log.i("TAG", "*********************************************************************");

        /**
         * isEmpty ——>map是否为空
         */

        boolean b3 = map.isEmpty();
        Log.i("TAG", "isEmpty ——>map是否为空----b3----:" + b3);
        Log.i("TAG", "****************************************************************");

        /**
         * map迭代方法1 ——>keySet()
         * keySet()把Map集合中的所有键都保存到一个Set类型的集合对象中返回。
         */

        Set<String> keyset = map.keySet();
        Iterator<String> i1 = keyset.iterator();
        while (i1.hasNext()) {
            String key = i1.next();
            String value = map.get(key);
            Log.i("TAG", "keySet迭代key----:" + key + "----value----:" + value);
        }
        Log.i("TAG", "******************************************************************");

        /**
         * map迭代方法2 ——>values()
         * values()把所有的值存储到一个Collection集合中返回,Collection<V> values():获取集合中所有值的集合。
         * 缺点: values方法只能返回所有 的值,没有键。
         */


        Collection<String> valuecollection = map.values();
        Iterator<String> i2 = valuecollection.iterator();
        while (i2.hasNext()) {
            String value = i2.next();
            Log.i("TAG", "values迭代" + "value----:" + value);
        }
        Log.i("TAG", "********************************************************************");

        /**
         * map迭代方法3 ——>entrySet()
         * entrySet()这种方法既能够获取键又能够获取值。
         */

        Set<Map.Entry<String, String>> keyvalue = map.entrySet();
        Iterator<Map.Entry<String, String>> i3 = keyvalue.iterator();
        while (i3.hasNext()) {
            Map.Entry<String, String> me = i3.next();
            String key = me.getKey();
            String value = me.getValue();
            Log.i("TAG", "entrySet迭代key----:" + key + "----value----:" + value);
        }
        Log.i("TAG", "******************************************************************");

        /**
         * remove ——>通过key 删除对应的values
         */

        map.remove("2");//通过key 删除对应的值

        Set<Map.Entry<String, String>> keyvalues = map.entrySet();
        Iterator<Map.Entry<String, String>> i3s = keyvalues.iterator();
        while (i3s.hasNext()) {
            Map.Entry<String, String> me = i3s.next();
            String key = me.getKey();
            String value = me.getValue();
            Log.i("TAG", "通过key 删除对应的values后entrySet迭代key----:" + key + "----value----:" + value);
        }
        Log.i("TAG", "******************************************************************");


        /**
         * clear ——>清空map中所有元素
         */

        map.clear();
        Log.i("TAG", "清空map中所有元素后len----:" + map.size());

    }

}

 

结果

 

I/TAG: get ——>根据key获取相应的values----str----:李四

I/TAG: get ——>根据key获取相应的values----allstr----:李四

I/TAG: ********************************************************************



I/TAG: size——>map长度----len----:4

I/TAG: size——>map长度----alllen----:4

I/TAG: *********************************************************************



I/TAG: containsKey(“key”)——>map中是否包含相应的key----b1----:true

I/TAG: **********************************************************************



I/TAG: containsValue(“values”)——>map中是否包含相应的values----b2----:true

I/TAG: *********************************************************************



I/TAG: isEmpty ——>map是否为空----b3----:false

I/TAG: ****************************************************************


I/TAG: keySet迭代key----:1----value----:张三

I/TAG: keySet迭代key----:2----value----:李四

I/TAG: keySet迭代key----:3----value----:王五

I/TAG: keySet迭代key----:4----value----:赵六

I/TAG: ******************************************************************



I/TAG: values迭代value----:张三

I/TAG: values迭代value----:李四

I/TAG: values迭代value----:王五

I/TAG: values迭代value----:赵六

I/TAG: ********************************************************************


I/TAG: entrySet迭代key----:1----value----:张三

I/TAG: entrySet迭代key----:2----value----:李四

I/TAG: entrySet迭代key----:3----value----:王五

I/TAG: entrySet迭代key----:4----value----:赵六

I/TAG: ******************************************************************



I/TAG: 通过key 删除对应的values后entrySet迭代key----:1----value----:张三

I/TAG: 通过key 删除对应的values后entrySet迭代key----:3----value----:王五

I/TAG: 通过key 删除对应的values后entrySet迭代key----:4----value----:赵六

I/TAG: ******************************************************************


I/TAG: 清空map中所有元素后len----:0

 

 

 

 

 

3.Map接口实现类之HashTable

 

<1> HashTable描述

HashTable是线程安全的一个Collection。

 

 

<2> HashTable使用demo

 

代码

package com.example.test;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initArrayList();
    }

    public void initArrayList() {
        Hashtable<String, String> hashtable = new Hashtable<String, String>();
        Hashtable<String, String> allhashtable = new Hashtable<String, String>();

        /**
         * put("key","value")——>“key”“values”
         */

        hashtable.put("1", "张三1");
        hashtable.put("2", "李四1");
        hashtable.put("3", "王五1");
        hashtable.put("4", "赵六1");

        /**
         * putAll(hashtable); ——>把一个hashtable全部放到另一个hashtable中
         */

        allhashtable.putAll(hashtable);

        /**
         * get ——>根据key获取相应的values
         */

        String str = hashtable.get("2");
        String allstr = allhashtable.get("2");
        Log.i("TAG", "get ——>根据key获取相应的values----str----:" + str);
        Log.i("TAG", "get ——>根据key获取相应的values----allstr----:" + allstr);
        Log.i("TAG", "*********************************************************************");

        /**
         * size——>hashtable长度
         */

        int len = hashtable.size();
        int alllen = allhashtable.size();
        Log.i("TAG", "size——>hashtable长度----len----:" + len);
        Log.i("TAG", "size——>hashtable长度----alllen----:" + alllen);
        Log.i("TAG", "************************************************************************");

        /**
         * containsKey(“key”)——>map中是否包含相应的key
         */

        boolean b1 = hashtable.containsKey("2");
        Log.i("TAG", "containsKey(“key”)——>hashtable中是否包含相应的key----b1----:" + b1);
        Log.i("TAG", "*******************************************************************");

        /**
         * containsValue(“values”)——>map中是否包含相应的values
         */

        boolean b2 = hashtable.containsValue("李四");
        Log.i("TAG", "containsValue(“values”)——>hashtable中是否包含相应的values----b2----:" + b2);
        Log.i("TAG", "*******************************************************************");

        /**
         * isEmpty ——>map是否为空
         */

        boolean b3 = hashtable.isEmpty();
        Log.i("TAG", "isEmpty ——>hashtable是否为空----b3----:" + b3);
        Log.i("TAG", "******************************************************************");

        /**
         * hashtable迭代方法1 ——>keySet()
         *  keySet()把Map集合中的所有键都保存到一个Set类型的集合对象中返回。
         */

        Set<String> keyset = hashtable.keySet();
        Iterator<String> i1 = keyset.iterator();
        while (i1.hasNext()) {
            String key = i1.next();
            String value = hashtable.get(key);
            Log.i("TAG", "keySet迭代key----:" + key + "----value----:" + value);
        }
        Log.i("TAG", "************************************************************");

        /**
         * hashtable迭代方法2 ——>values()
         * values()把所有的值存储到一个Collection集合中返回,Collection<V> values():获取集合中所有值的集合。
         * 缺点: values方法只能返回所有 的值,没有键。
         */


        Collection<String> valuecollection = hashtable.values();
        Iterator<String> i2 = valuecollection.iterator();
        while (i2.hasNext()) {
            String value = i2.next();
            Log.i("TAG", "values迭代" + "value----:" + value);
        }
        Log.i("TAG", "******************************************************************");

        /**
         * hashtable迭代方法3 ——>entrySet()
         * entrySet()这种方法既能够获取键又能够获取值。
         */

        Set<Map.Entry<String, String>> keyvalue = hashtable.entrySet();
        Iterator<Map.Entry<String, String>> i3 = keyvalue.iterator();
        while (i3.hasNext()) {
            Map.Entry<String, String> me = i3.next();
            String key = me.getKey();
            String value = me.getValue();
            Log.i("TAG", "entrySet迭代key----:" + key + "----value----:" + value);
        }
        Log.i("TAG", "**********************************************************");

        /**
         * remove ——>通过key 删除对应的values
         */

        hashtable.remove("2");//通过key 删除对应的值
        Set<Map.Entry<String, String>> keyvalues = hashtable.entrySet();
        Iterator<Map.Entry<String, String>> i3s = keyvalues.iterator();
        while (i3s.hasNext()) {
            Map.Entry<String, String> me = i3s.next();
            String key = me.getKey();
            String value = me.getValue();
            Log.i("TAG", "通过key 删除对应的values后entrySet迭代key----:" + key + "----value----:" + value);
        }
        Log.i("TAG", "**********************************************************");

        /**
         * clear ——>清空hashtable中所有元素
         */

        hashtable.clear();
        Log.i("TAG", "清空hashtable中所有元素后len----:" + hashtable.size());

    }

}

 

结果

I/TAG: get ——>根据key获取相应的values----str----:李四1

I/TAG: get ——>根据key获取相应的values----allstr----:李四1

I/TAG: *********************************************************************

I/TAG: size——>hashtable长度----len----:4

I/TAG: size——>hashtable长度----alllen----:4

I/TAG: ************************************************************************

I/TAG: containsKey(“key”)——>hashtable中是否包含相应的key----b1----:true

I/TAG: *******************************************************************

I/TAG: containsValue(“values”)——>hashtable中是否包含相应的values----b2----:false

I/TAG: *******************************************************************

I/TAG: isEmpty ——>hashtable是否为空----b3----:false

I/TAG: ******************************************************************

I/TAG: keySet迭代key----:4----value----:赵六1

I/TAG: keySet迭代key----:3----value----:王五1

I/TAG: keySet迭代key----:2----value----:李四1

I/TAG: keySet迭代key----:1----value----:张三1

I/TAG: ************************************************************

I/TAG: values迭代value----:赵六1

I/TAG: values迭代value----:王五1

I/TAG: values迭代value----:李四1

I/TAG: values迭代value----:张三1

I/TAG: ******************************************************************

I/TAG: entrySet迭代key----:4----value----:赵六1

I/TAG: entrySet迭代key----:3----value----:王五1

I/TAG: entrySet迭代key----:2----value----:李四1

I/TAG: entrySet迭代key----:1----value----:张三1

I/TAG: **********************************************************

I/TAG: 通过key 删除对应的values后entrySet迭代key----:4----value----:赵六1

I/TAG: 通过key 删除对应的values后entrySet迭代key----:3----value----:王五1

I/TAG: 通过key 删除对应的values后entrySet迭代key----:1----value----:张三1

I/TAG: **********************************************************

I/TAG: 清空hashtable中所有元素后len----:0

也就是说HashTable输出和插入的顺序不一样。即无序的。

以上可以看出HashMapHashTable用法完全一样,只是底层实现不一样。

 

 

 

 

 

 

五.总结

 

Java容器实际上只有三种:List, Set,Map 但每种接口都有不同的实现版本.它们的区别可以归纳为由什么在背后支持它们.也就是说,你使用的接口是由什么样的数据结构实现的。

 

 

List的选择

         ArrayList和LinkedList都实现了List接口。因此无论选择哪一个基本操作都一样。但ArrayList是由数组提供底层支持。而LinkedList是由双向链表实现的。所以,如果要经常向List里插入或删除数据LinkedList会比较好。否则应该用速度更快的ArrayList。

 

 

Set的选择

         HashSet总是比TreeSet性能要好。而后者存在的理由就是它可以维持元素的排序状态。所以,如果需要一个排好序的Set时,才应该用TreeSet。

 

Map选择
        同上,尽量选择HashMap。

 

 

 

附:Collection官方文档

https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值