基础系列【十三】--集合

集合

1.容器用来储存数据的数据结构。 变量时最小的容器--只能存一个数据。
2. Collection--集合的顶级父接口。java.util.Collection,一组Collection代表一组对象。集合中只能存对象(实际上存的是对象的引用)。
    1. Collection没有任何的实现类。其下有两个子接口List和Set。
        1. List(JDK1.2才出现)的实现类
            1. ArrayList--底层基于数组,有序,可重复集。
                1. 默认数组的大小为10,每次扩容为1.5倍(扩容的实现为位运算)。
                2. 内存空间是连续的,可以基于下标进行操作集合。查找效率高,插入和删除效率低。
                3. 线程是不安全的。
            2. LinkedList--底层基于链表实现。
                1. 内存空间不连续,基于节点储存元素(first data last),查询慢,插入和删除效率高。
                2. 线程不安全。
            3. vector:JDK1.0就有了,JDK1.2开始实现List接口,是最早的集合类之一。基于数组实现,默认数组的大小为10,扩容时,每次扩大一倍(基于三目运算)。
                1. 内存空间连续。有序,可重复集。查询效率高,插入和删除效率慢。
                2. 线程安全。
            4. Stack:栈。遵循LILO(先进后出)原则。
                1. 基于Vector实现,线程安全。

List(JDK1.2才出现)

list有序的,按照元素存入的顺序排序(有下标,从0开始)。可重复的。
     提供了一些基于下标的操作
     E set(int index, E element) 用指定元素替换列表中指定位置的元素(可选操作)。 
     E get(int index) 返回列表中指定位置的元素。 
     boolean equals(Object o) 比较指定的对象与列表是否相等。 比较方式按照元素位置依次比较。比较方式:equals
    /*public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;

        ListIterator<E> e1 = listIterator();
        ListIterator e2 = ((List) o).listIterator();
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }*/
     E remove(int index) 移除列表中指定位置的元素(可选操作)。 
     int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1 
     int lastIndexOf(Object o) 
     List<E> subList(int fromIndex, int toIndex) 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视

ArrayList

//List的实现类,大小可变的列表,基于数组,默认初始大小初始为10;每次扩容为原数组的1.5倍。
// 因为ArrayList是基于数组实现的,内存空间是连续的。插入或者删除元素的时候效率会较低。但查询效率很快。
// 线程不安全的集合。
// 练习:用数组实现一个ArrayList(有序表)。
public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<String>();

    System.out.println(list.toString());
}

LinkedList

//基于链表。用节点(NODE)储存元素。内存空间不连续,删除和插入效率高。查询元素效率低,线程不安全的集合。
    List<String> link = new LinkedList<>();

Vector

 List--JDK1.2
// Vector:向量,java中最早的集合之一(JDK.10)。底层基于数组,默认数组长度10,每次扩容1倍.10--20--40,基于三元运算.
// 线程安全的集合。
public static void main(String[] args) {
    Vector<String> v = new Vector<>(10, 5);
    v.add("a");
    // Enumeration<E> elements() 返回此向量的组件的枚举(迭代器)。
    // 迭代器,基于指针移动。遍历每个元素。
    /*
     * boolean hasMoreElements() 测试此枚举是否包含更多的元素。 
       E nextElement() 如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
     */
     Enumeration<String> e = v.elements();
     while (e.hasMoreElements()) {
         // 移动指针,挪到下一个元素。
        String s = (String) e.nextElement();
        System.out.println(s);
        //v.remove(s);这种方式移不完集合。
    }
    System.out.println(v.capacity());// 10
}

Stack

// Stack:栈。(Vector的子类),遵循LILO原则(后进先出)。基于Vector实现。线程安全的集合。
// 向栈中添加元素,入栈/压栈。将元素取出:出栈/弹栈。
// 栈底元素:第一个放进的元素。 栈顶元素:最后一个放进去的元素。
// 练习:用数组实现栈结构--pop、push、peek、empty、search
// 总结:list和数组区别?--大小,元素类型,内存空间。
// ArrayList LinkedList Vector的异同点?根据插入的位置不同而不同。
// 从整体(平均)效率上,LinkedList会较快。从局部效率上,在不扩容的前提下,如果插入的位置比较靠后,则ArrayList会比较快。

public static void main(String[] args) {
    Stack<String> s = new Stack<String>();
    // public E push(E item)
    // public synchronized E pop() ;将栈顶元素取出,并移除。
    // public synchronized E peek() ;查看栈顶元素,不将栈顶元素取出。
    // public synchronized int search(Object o) ;搜索某元素在栈中的位置,下标从1开始。
}

Set

1. Set--不包含重复值。不保证元素的迭代顺序(存入顺序),不保证该顺序恒久不变。
2. set集合的实现类
    1. HashSet:
        1. 底层基于HashMap的实例实例实现。
        2. 要求key不可重复。由哈希算法确定储存桶位置。
        3. 允许key为null
        3. 线程不安全的集合      
    2. LinkedHashSet
        1. 底层是Hash表和双向链表。
        2. 具有可预知迭代顺序的(元素的插入顺序)
        3. LinkedHashSet 迭代所需时间与 set 的大小 成正比,而与容量无关
        4. 由于增加了维护链接列表的开支,其性能很可能会比 HashSet 
        5. 影响其性能的参数:初始容量 和加载因子。
        6. 线程不安全的集合
    3. treeSet
  public static void main(String[] args) {
//Set--不包含重复值。不保证元素的迭代顺序(存入顺序),不保证该顺序恒久不变。
/*
 * HashSet--底层是HashMap,默认储存空间(桶)16,当元素超桶容量的0.75的时候,则会扩容一倍,并进行reHash操作--重新计算元素的储存位置。。
 * 元素在存入到HashSet表中的时候,会根据对象的Hash码值,经哈希算法,计算出元素的存储桶位置。
 * 不同的对象有不同的hash码值,但在经过哈希算法计算之后可能产生相同的储存桶位置。
 * 那么这个时候就会产生碰撞,碰撞过程--会用equals比较两个对象是否相同,相同则后储存的对象直接舍弃。若不同则会将原来的储存位置向下一位移动。
 * 若下一位,也有元素,则也会产生碰撞,知道找个空桶储存为止。
 * 碰撞几率问题:碰撞几率和桶容量和加载因子大小有关。我们在创建Set集合的时候可以通过构造函数可以指定容量大小和加载因子。
 * 构造--指定容量和加载因子?100-1--碰撞几率增加--效率下降。100-0.5-扩容频繁,内存消耗增加,rehash操作也很频繁。
 * 加载因子(警戒线)0.75--若容量超过75%则需扩容。16*0.75=12,当超过12时即13,则会扩容。
 */
Set<String> set = new HashSet<String>();

}

Iterator

1. 迭代器,用于迭代遍历集合---在迭代过程中不允许增删原集合
Iterable提供了一个iterator方法来产生一个Iterator对象。
增强for循环本质上在迭代遍历。---如果一个对象允许使用增强for循环遍历,则这个对象对应的类必须实现Iterable接口。---JDK1.	
public class IteratorDemo {
// public interface Iterable<T>(JDK1.5开始):实现这个接口允许对象成为 "foreach" 语句的目标。(提供了一个,可以获取Iterator对象的方法)
// 增强foreach(JDK1.5的特性之一):本质就是迭代器,进行迭代遍历
// JDK1.5新特性:增强foreach,泛型,自动拆封箱
// 在迭代过程中,不允许增加或删除原集合。
// Enumeration接口的功能与 Iterator 接口的功能是重复的。此外,
// Iterator 接口添加了一个可选的移除操作,并使用较短的方法名。
// 新的实现应该优先考虑使用 Iterator
// 接口而不是 Enumeration 接口
public static void main(String[] args) {
    Set<String> set = new HashSet<String>();
    set.add("a");
    set.add("b");
    set.add("c");
    // 获取集合的迭代器
    Iterator<String> it = set.iterator();
    while (it.hasNext()) {// 判断是否有下一个元素
        // 移动指针,获取下一个元素
        String str = it.next();
        System.out.println(str);
        // 移除当前迭代的元素
        // 1.将原集合复制 2 每一个元素标记为False
        // 3.遍历集合(判断-移动指针(把指针指向的位置标志为T:标识元素是存在)
        // 4.当it.remove()时候,会将该指针指向的位置,标记职位F,副本集合再和原集合比较,标记为true保留,false则移除。)
        it.remove();
        // set.remove();
    }
}

Collections

1. 操作集合的工具类提供了很多操作集合的方法。
public class CollectionsDemo {
// Collections:操作集合的工具类。
public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("a");
    list.add("d");
    list.add("ab");
    list.add("e");
    list.add("f");
    // 替换原集合所有的"a"
    Collections.replaceAll(list, "a", "1");
    System.out.println(list);

    // 将集合反转
    Collections.reverse(list);
    System.out.println(list);

    // 集合升序排列
    Collections.sort(list);
    System.out.println(list);

    // 将数组转化为一个集合
    List<String> lis = Arrays.asList("John", "Tome", "Toms", "Jack", "Jerry");

    // //升序排列
    // Collections.sort(lis);
    System.out.println(lis);
    // 自定义规则:Comparator:接口,比较器,重写Compare方法,将比较规则写到Compare方法中。一个类想要实现自定义排序,可以实现该接口
    // Comparable:接口,若果不指定比较规则,一个类想要被自然排序,必须实现该接口,可以重ComparaeTo方法,定义比较规则。
    // 按照首字母升序排列
    Collections.sort(lis, new Comparator<String>() {
        // 返回一个正数,s1>s2,则s1就会排在s2的后面
        // 返回0,不做排序
        @Override
        public int compare(String o1, String o2) {
            return o1.charAt(0) - o2.charAt(0);
        }
    });
    System.out.println(lis);
}
}

Comparator

1. 比较器。重写compare方法,将比较规则写到compare方法中。
2. 如果返回一个正数,则意味着第一个参数要排在第二个参数后边;
3. 如果返回一个负数,则意味着第一个参数要排在第二个参数前边。
4. 如果在排序的时候没有指定比较规则,那么这个时候要求排序的元素所对应的类必须实现Comparable接口,重写接口中compareTo方法

下一篇:
基础系列【十四】–Map映射

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值