集合家族史--成员,成员结构,成员特性,各自的使用场景应用

Collection
tps
集合只能存储引用类型 ?这个是疑问点
String :执行操作数据的方式:删除,增加

StringBuffer

数据结构

百度百科说:数据结构是计算机存储、组织数据的方式。 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
常见的数据结构有:数组、堆和队列、链表、二叉树、红黑树、哈希表及图形
简单排序,递归和进阶排序

Collection

Collection接口是处理对象集合的根接口,其中定义了很多对元素进行操作的方法,AbstractCollection是提供Collection部分实现的抽象类。

LIst 里面的操作

ArrayList

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
 transient Object[] elementData;

ArrayList中用elementData保存数据。底层是Object类型的数组
ArrayList 里面接口定义:
RandomAccess
RandomAccess接口是一个标志接口(Marker),实现了RandomAccess说明,该List接口支持快速随机访问(ArrayList实现了该接口,当遍历时用普通for循环会高效些(该部分会在后续标题Collections中指出),而LinkedList未实现该接口,遍历时用Iterator或者forEach高效些)
Cloneable:
java.io.Serializable:对象的寿命通常随着生成该对象的程序的终止而终止,而有时候需要把在内存中的各种对象的状态(也就是实例变量,不是方法)保存下来,并且可以在需要时再将对象恢复。 Java提供了一种保存对象状态的机制,那就是序列化。
()ArrayList中装载元素的elementData为什么被transient修饰?

    transient Object[] elementData; // non-private to simplify nested class access

transient表示这个域不是该对象序列化的一部分,而ArrayList又是可序列化的类,当对象发生序列化,再反序列化,那被transient修饰的字段就会消失。幸好,ArrayLIst还有另一个机制,就是 arrayList在序列化的时候会调用writeObject,直接将size和element写入ObjectOutputStream;反序列化时调用readObject,从ObjectInputStream获取size和element,再恢复到elementData。

ArrayList里面的关键
—LinkedList

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList 底层是由双向链表组成的List集合,LinkedList的元素添加和删除其实就对应着链表节点的添加和移除

  //存储的元素个数
transient int size = 0;
//头节点
transient Node<E> first;
//尾节点
transient Node<E> last;

linkedList 还实现了Deque接口,Deque父接口为Queue,也就是说linkeList 底层还实现了队列。
什么是队列,队列是一种先进先出的数据结构,元素在队列末尾添加,在队列头部删除。Queue接口扩展自Collection,并提供插入、提取、检验等操作。
– Vector

    public synchronized boolean addAll(int index, Collection<? extends E> c)

vector里面的方法是用synchronized 修饰的,也就是说该方法是同步的,当发生多线程访问时,可保证数据一致性

@Slf4j
public class ListHH {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add("heaan");
        arrayList.add("hhh");
        arrayList.add(1);
        arrayList.add(89);

        System.out.println("使用 Iterator进行迭代,现在的list是" + JSON.toJSONString(arrayList));
        Iterator iterator = arrayList.iterator();
        System.out.println("iterator 对象是" + iterator);
        while (iterator.hasNext()) {
            Object object = iterator.next();
            System.out.println("打印每次进来的元素" + JSON.toJSONString(object));
            if ("hhh".equals(object)) {
                iterator.remove();
            }
            log.info("this data is {}",JSON.toJSONString(object));
              //  log.info("this data is {}", JSON.toJSONString(iterator));// 这段代码被注释掉了。因为保留的话。json.toJSONString(iterator)会将iterator里面的数据全部迭代完毕,导致其他的元素没有接着走hasNext()代码块。
        }
        log.info("最后打印的data是 {}",JSON.toJSONString(iterator));// 因为hasNext()方法已经把iterator迭代完毕了,所有当 while (iterator.hasNext())代码块跳出的时候,iterator已经是空数组了。
    }


}

控制台打印的结果是

使用 Iterator进行迭代,现在的list是["heaan","hhh",1,89]
iterator 对象是java.util.ArrayList$Itr@58651fd0
打印每次进来的元素"heaan"
[23:11:36.422][INFO][com.mmall.ListHH][main] this data is "heaan"
打印每次进来的元素"hhh"
[23:11:36.426][INFO][com.mmall.ListHH][main] this data is "hhh"
打印每次进来的元素1
[23:11:36.427][INFO][com.mmall.ListHH][main] this data is 1
打印每次进来的元素89
[23:11:36.427][INFO][com.mmall.ListHH][main] this data is 89
[23:11:36.449][INFO][com.mmall.ListHH][main] 最后打印的data是 []

map 接口里面的操作

接口定义:

public interface Map<K,V>

– HashMap

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable 

– HashTable

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable

– LinkedHashMap

public class MapHH {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("1", "value1");
        map.put("2", "value2");
        map.put("3", "value3");

        System.out.println("通过map.keySet遍历key和value:");
        for (String key : map.keySet()) {
            System.out.println("key =" + key + " and value=" + map.get(key));
        }

        System.out.println("通过map.entrySet使用Iterator遍历key和value");
        Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            System.out.println("key=" + entry.getKey() + " and value =" + entry.getValue());

        }


        System.out.println("使用map.entrySet 遍历key和value");
        for (Map.Entry<String, String> entry :
                map.entrySet()) {
            System.out.println("key=" + entry.getKey() + " and value =" + entry.getValue());

        }

        System.out.println("通过map.values()遍历所有的value,但是不能遍历key");
        for (String v : map.values()
        ) {
            System.out.println("value =" + v);


        }
    }
}

set里面的操作

HashSet

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable

查看散列集HashSet的源码实现可以看到它内部是使用一个HashMap来存放元素的,因为HashSet的元素就是其内部HashMap的键集合,所以所以HashSet可以做到元素不重复。

– LInkedHashSet
LinkedHashSet是继承自HashSet的,支持对规则集内的元素排序。LinkedHashSet中的元素可以按照它们插入规则集的顺序提取
– TreeSet
TreeSet扩展自AbstractSet,并实现了NavigableSet,AbstractSet扩展自AbstractCollection,树形集是一个有序的Set,其底层是一颗树,这样就能从Set里面提取一个有序序列了。在实例化TreeSet时,我们可以给TreeSet指定一个比较器Comparator来指定树形集中的元素顺序。树形集中提供了很多便捷的方法。

数组和集合和字符串之间的转化

字符串转化成数组
String[] s = string.split(","); // 返回数组
数组转化成集合
Arrays.asList(数组); // 返回集合arrayList类型
集合转化成数组
arrayList.toArray();
数组转化成字符串
char类型的数组,可直接使用String.valueOf(数组);
包装数据类型的数组,可借助stringBuffer.append 和遍历。

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

        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("hhh");
        arrayList.add("tengfei");

        // 集合转化成数组
        String[] strings = arrayList.toArray(new String[arrayList.size()]);
        System.out.println("当前数组打印数据是"+String.valueOf(strings)); //输出的是[Ljava.lang.String;@3e3abc88    String.valueOf()方法里面的参数可以是int类型,也可以是Object类型
        // 数组转化成字符串
        StringBuffer stringBuffer = new StringBuffer();
        for (String s :
                strings) {
            stringBuffer.append(s);

        }

        // 数组转化成集合
        List<String> list = Arrays.asList(strings);

        // 字符串转化成集合--- 整体的思想就是字符串先转化成数组,再转化成集合
        String a = "a,m,hj";
        String[] help = a.split(",");
       /* for (String b:
            help ) {
            System.out.println(b);

        }*/

        List<String> list1 = Arrays.asList(help);
        for (String b : list1
        ) {
            System.out.println(b);

        }


        char[] chars  = {'a','b','c'};
        String s= String.valueOf(chars);
        System.out.println("char[] 基本数据类型直接用String.valueOf()打印的是abc"+s);

        int[] ints ={1,3,5};
        String s1 =  String.valueOf(ints);
        System.out.println("int 基本数据类型直接用String.valueOf打印打印的是[I@6ce253f1"+s1);
    }

Collections

collections也是Java util包下的一个包装类,其是服务于collection的一个工具类,包括的方法有集合中元素进行排序、复制、搜索

// for(循环初始值;循环条件;循环参数)

      for (String i:linkedList){ }    // 该效果等同于下面这句 实际上forEach语句用的就是iterator
      for (Iterator iterator = linkedList.iterator();iterator.hasNext();){}
 @Test
    public void SpeedTest() {

        List<String> arrayList = new ArrayList<String>();
        for (int i = 0; i < 800000; i++) {
            arrayList.add("" + i);

        }
        long loopTime = CollectionT.traverseByLoop(arrayList);
        long iteratorTime = CollectionT.traverseByIterator(arrayList);
        log.info("ArrayList比对使用两种方式遍历时间开始,普通for运行的时间为{},iterator或者foreach 运行的时间为{}", loopTime, iteratorTime);

        List<String> linkedList = new LinkedList<String>();


        for (int i = 0; i < 80000; i++) {
            linkedList.add("" + i);
        }
        long linkLoopTime = CollectionT.traverseByLoop(linkedList);
        long linkIteratorTime = CollectionT.traverseByIterator(linkedList);
        log.info("LinkedList比对使用两种方式遍历时间开始,普通for运行的时间为{},iterator或者foreach 运行的时间为{}", linkLoopTime, linkIteratorTime);


    }

// 使用普通for循环的代码

 public static long traverseByLoop(List list) {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < list.size(); i++) {
            list.get(i);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }

// 使用迭代器的代码

//使用迭代器遍历
    public static long traverseByIterator(List list) {
        Iterator iterator = list.iterator();
        long startTime = System.currentTimeMillis();
        while (iterator.hasNext()) {
            iterator.next();
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }

Arrays

package com.aicai.qa.junit5test.projecttest;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.util.*;

import static org.junit.jupiter.api.Assertions.*;


@Slf4j
public class CollectionT {
    ArrayList<String> arrayList;
    LinkedList<String> linkedList;
    LinkedList<String> stringLinkedList;
    HashMap<Integer, String> hashMap;

    @BeforeAll
    public void init() {
        arrayList = new ArrayList<String>();
        linkedList = new LinkedList<String>();
        stringLinkedList = new LinkedList<>();
        hashMap = new HashMap<Integer, String>();

    }

    @Test
    public void testGson() {
        Gson gson = new Gson();
        int i = gson.fromJson("100", Integer.class);
        System.out.println(i);
        String a = gson.toJson(false);
        System.out.println(a);
    }

    @org.junit.jupiter.api.Test
    public void testArraysCopyOf() {
        int[] arr = {1, 2, 3, 4, 5};
        int[] copied = Arrays.copyOf(arr, 10);
        System.out.println(Arrays.toString(copied));

        copied = Arrays.copyOf(arr, 3);// Arrays.copyOf()底层调用了System.arraycopy  不仅仅只是拷贝数组中的元素,在拷贝元素时,会创建一个新的数组对象
        System.out.println(Arrays.toString(copied));

    }

    @Test
    public void testArrayList() {
        stringLinkedList.add("uuu");// 另一个集合
        stringLinkedList.add("hhh");// 另一个集合
        linkedList.add("jjj"); // 第二个集合
        arrayList.add("hhh");
        arrayList.add("uuu");
        arrayList.add("yyy");
        arrayList.add("xxx");
        arrayList.addAll(linkedList);// 添加所有到arrayList
        arrayList.remove(1);
        System.out.println("arrlist 集合是" + arrayList); // 应该删除uuu
        arrayList.remove("xxx");

//        log.info(arrayList);

        assertAll("校验集合containsAll,contains,get,size方法",
                () -> assertEquals("hhh", arrayList.get(0), "校验获取的第一个下标对应数据一致"),
                () -> assertTrue(arrayList.containsAll(stringLinkedList), "校验ArrayList是否包含linkedLIst对象"),
                () -> assertTrue(arrayList.contains("hhh"), "校验ArrayList是否包含hhh"),
                () -> assertEquals(5, arrayList.size()),
                () -> assertTrue(!arrayList.isEmpty())
        );
        for (String s : arrayList
        ) {
            log.info(s);

        }

        // contains
        log.info("arrayList 对象是否存在指定object  " + arrayList.contains("hhh"));
        // toArray()  转换成数组
        String[] strings = arrayList.toArray(new String[arrayList.size()]);// array List的长度和 集合转化成数组
        log.info("string 数组是" + JSON.toJSONString(strings));

        // Arrays.toList(数组转化成集合)
        List<String> list = Arrays.asList(strings);
        log.info("list 集合是" + JSON.toJSONString(list));


    }

    @Test
    public void testLinkedList() {
        // 链表末尾添加一个新节点
        linkedList.add("aa");
        // 向链表指定位置添加一个新节点
        linkedList.add(1, "bb");
        System.out.println("add 后的数据是" + JSON.toJSONString(linkedList));
        linkedList.addFirst("cc");// 进栈操作
        System.out.println("addFirst 后的数据是" + JSON.toJSONString(linkedList));
        linkedList.addLast("dd");// 入队操作
        System.out.println("addLast 后的数据是" + JSON.toJSONString(linkedList));// cc aa bb dd
        System.out.println(linkedList.removeFirst());// 出队操作
        System.out.println("remove 之后的数据是" + JSON.toJSONString(linkedList));
        System.out.println(linkedList.getFirst());
        System.out.println(linkedList.getLast());

        //向链表表尾添加一个新节点
        log.info("当前LInkedList 对象是" + JSON.toJSONString(linkedList));
        // 删除第一个节点并返回这个节点中的对象
        linkedList.removeFirst();
        // 删除指定位置的节点,并返回对象
        linkedList.remove(1);
        // 得到链表第一个节点的对象
        log.info(linkedList.getFirst());
        // 入队操作
        enqueue("hhh", linkedList);
        log.info(JSON.toJSONString(linkedList));
        // 出队操作
        dequeue(linkedList);
        log.info(JSON.toJSONString(linkedList));

    }


    @Test
    public void testHashSet() {
        // 交集
        Set<String> set1 = new HashSet<>(3);
        Set<String> set2 = new HashSet<>(3);
        set1.add("1");
        set1.add("2");

        set2.add("1");
        set2.add("5");


        Set<String> retainAllSet = (Set<String>) retainAll(set1, set2);

        Set<String> removeAllSet = (Set<String>) removeAll(set1, set2);

        Set<String> addAllSet = (Set<String>) addAll(set1, set2);

        log.info("retainAllSet is {}", JSON.toJSONString(retainAllSet));
        log.info("removeAllSet is {}", JSON.toJSONString(removeAllSet));
        log.info("addAllSet is {}", JSON.toJSONString(addAllSet));

    }

    @Test
    public void testHashMap() {
        hashMap.put(1, "一");
        hashMap.get(1);
        hashMap.get(1);
        for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
        }

    }

    // 入队
    private void enqueue(Object e, LinkedList list) {
        list.addLast(e);
    }

    // 出队
    private Object dequeue(LinkedList list) {
        return list.removeFirst();
    }


    /**
     * 取交集
     *
     * @param c1
     * @param c2
     * @return
     */
    private Collection<String> retainAll(Collection<String> c1, Collection<String> c2) {
        c1.retainAll(c2);
        return c1;
    }

    /**
     * 差集
     *
     * @param c1
     * @param c2
     * @return
     */
    private Collection<String> removeAll(Collection<String> c1, Collection<String> c2) {
        c1.removeAll(c2);
        return c1;
    }

    /**
     * 并集
     *
     * @param c1
     * @param c2
     * @return
     */
    private Collection<String> addAll(Collection<String> c1, Collection<String> c2) {
        c1.addAll(c2);
        return c1;
    }

    @Test
    public void testCollections() {
        ArrayList nums = new ArrayList();
        nums.add(8);
        nums.add(2);
        nums.add(9);
        nums.add(-2);
        System.out.println("arraylist add 之后的数据是" + nums);
        Collections.reverse(nums);
        System.out.println("reverse 反转后的数据是" + nums);

        Collections.sort(nums);
        System.out.println("sort 排序按自然排序的升序排序之后的数据是" + nums);
        Collections.shuffle(nums);
        System.out.println("随机排序之后的数据是" + nums);
        //下面只是为了演示定制排序的用法,将int类型转成string进行比较

//        System.out.println(nums);

        System.out.println("max筛选后的collection集合是" + Collections.max(nums));
        System.out.println("min筛选后的collection集合是" + Collections.min(nums));
        Collections.replaceAll(nums, -2, -7);
        System.out.println("replaceAll 之后的collection是" + nums);
        System.out.println("统计元素出现次数是" + Collections.frequency(nums, 2));
        Collections.sort(nums);
        System.out.println(Collections.binarySearch(nums, 5));

        List list = Collections.synchronizedList(nums);// 返回同步的list
    }


    @Test
    public void testArrays() {

    }

    /**
     * 校验randomAccess下 ArrayList和LinkedList遍历的时间。
     */
    @Test
    public void SpeedTest() {

        for (int i = 0; i < 100000; i++) {
            arrayList.add("" + i);
            linkedList.add("" + i);

        }
        long loopTime = CollectionT.traverseByLoop(arrayList);
        long iteratorTime = CollectionT.traverseByIterator(arrayList);
        long linkLoopTime = CollectionT.traverseByLoop(linkedList);
        long linkIteratorTime = CollectionT.traverseByIterator(linkedList);
        log.info("ArrayList比对使用两种方式遍历时间开始,普通for运行的时间为{},iterator 运行的时间为{}", loopTime, iteratorTime);
        log.info("LinkedList比对使用两种方式遍历时间开始,for运行的时间为{},iterator 运行的时间为{}", linkLoopTime, linkIteratorTime);


    }

    @Test
    public void testIsOrNotImplentsRandomAccess() {
        ArrayList<String> arrayList = new ArrayList<String>(8);
        arrayList.add("hhhh");
        arrayList.add("nihao");
        traverse(arrayList);
    }


    public void tests() {
        for (String i : linkedList) {
        }
        for (Iterator iterator = linkedList.iterator(); iterator.hasNext(); ) {
        }
    }

    /**
     * 使用for循环遍历
     *
     * @param list
     * @return
     */
    public static long traverseByLoop(List list) {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < list.size(); i++) {
            list.get(i);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }


    //使用迭代器遍历
    public static long traverseByIterator(List list) {
        Iterator iterator = list.iterator();
        long startTime = System.currentTimeMillis();
        while (iterator.hasNext()) {
            iterator.next();
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }


    public static void traverse(List list) {

        if (list instanceof RandomAccess) {
            log.info("实现了RandomAccess接口,不使用迭代器");

            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }

        } else {
            log.info("没实现RandomAccess接口,使用迭代器");

            Iterator it = list.iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }

        }
    }


    @Test
    public void testArray() {
        String[] s = new String[3];
        s[0] = "1";
        s[1] = "2";
//        s[2]="3";
        // Stream.of(s).forEach(s1-> System.out.println(s1));
        System.out.println(s.length);
        System.out.println(s[0]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值