集合知识点总结(一)

Iterator 迭代器

  • Iterator 接口 :JDK提供的遍历集合所有元素的接口

    • 迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
    * `public E next()`:返回迭代的下一个元素。
    * `public boolean hasNext()`:如果仍有元素可以迭代,则返回 true。
    * public void remove() {//删除元素
    

    注意:在使用.hasnext().next方法时需交替出现类要具有迭代器 需要实现iterable接口

  •       自定义类迭代器类需要实现Iterator<E>接口
    

    并发异常问题:ConcurrentModificationException

  •       原因:集合本身修改会引起modount版本号改变,而迭代器本身的版本号副本并未改变,所以会抛出异常
    
  • fair -fast机制----》快速失败机制

  • fast-fail事件产生的条件:当多个线程对Collection进行操作时,若其中某一个线程通过iterator去遍历集合时,该集合的内容被其他线程所改变;则会抛出ConcurrentModificationException异常。
    fast-fail解决办法:通过util.concurrent集合包下的相应类去处理,则不会产生fast-fail事件。

  • tertor和Listiterator的区别和相同点

  • itertor 对 collection 进行迭代的迭代器

  1. ListIterator有add()方法,可以向List中添加对象,而Iterator不能
  2. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
  3. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
  4. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改
  • 迭代器的实现原理
    当遍历集合时,首先通过调用t集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。

Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素:
在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。


单例集合 --Java.util

Colection :单例集合的根接口,用于存储一系列符合某种规则的元素,有两个重要的子接口

* `public boolean add(E e)`:  把给定的对象添加到当前集合中 。
* `public void clear()` :清空集合中所有的元素。
* `public boolean remove(E e)`: 把给定的对象在当前集合中删除。
* `public boolean contains(E e)`: 判断当前集合中是否包含给定的对象。
* `public boolean isEmpty()`: 判断当前集合是否为空。
* `public int size()`: 返回集合中元素的个数。
* `public Object[] toArray()`: 把集合中的元素,存储到数组中。
LIst : 特点是元素有序,元素可重复,可通过索引检索 有三个实现类

接口介绍:public interface Linke extends Colection
1> 有序集合(也称序列) ,可通过索引精确访问每个位置
2> LIst接口提供了特殊的迭代器 LIstIterator,允许元素插入和更换 ,提供了从指定位置开始迭代的方法
3> 允许元素重复,可通过元素的 .equals() 比较是否为重复元素
4>List集合取出元素的方式可以采用:迭代器、增强for。

常用方法:
- `public void add(int index, E element)`: 添加到该集合中的指定位置上。
- `public E get(int index)`:返回集合中指定位置的元素。
- `public E remove(int index)`: 移除列表中指定位置的元素。
- `public E set(int index, E element)`:用指定元素替换集合中指定位置的元素。
  • Vector :
    实现类介绍:public class Vectorextends AbstractListimplements List, RandomAccess, Cloneable, Serializable
    1>Vector类实现了可扩展的对象数组。
    2>快速失败
    3>每个向量尝试通过维护capacity和capacityIncrement优化存储capacityIncrement 。 capacity总是至少与矢量大小一样大; 通常较大,因为当向量中添加组分时,向量的存储空间大小capacityIncrement 。
  public static void main(String[] args) {
        Vector <String >vr=new Vector<>() ;
        vr.add("A") ;
        vr.add("B") ;
        vr.add("C") ;
        vr.add("D") ;
        vr.add("E") ;
        vr.add("F") ;
       // 返回此向量的组件的枚举。
        Enumeration <String>it=vr.elements();
        while (it.hasMoreElements() ){
            String s=it .nextElement() ;
            System.out.print(s+" ");
        }
        System.out.println();
        // 返回此 List 的部分视图,元素范围为从 fromIndex(包括)到 toIndex(不包括)。
        List <String>list =vr .subList(1,4);
        System.out.println(list);
        Iterator <String>itor=vr.iterator() ;
       while (itor .hasNext() ){
           String s=itor .next() ;
           System.out.print(s+" ");
       }
    }
  • LinkedList :
    实现类介绍
    1>双链表实现了List和Deque接口。 实现所有可选列表操作,并允许所有元素(包括null )。
    2>*请注意,此实现不同步 * 类外部同步/包装 List list = Collections.synchronizedList(new ArrayList(…));
    3>快速失败
* `public void addFirst(E e)`:将指定元素插入此列表的开头。
* `public void addLast(E e)`:将指定元素添加到此列表的结尾。
* `public E getFirst()`:返回此列表的第一个元素。
* `public E getLast()`:返回此列表的最后一个元素。
* `public E removeFirst()`:移除并返回此列表的第一个元素。
* `public E removeLast()`:移除并返回此列表的最后一个元素。
* `public E pop()`:从此列表所表示的堆栈处弹出一个元素。
* `public void push(E e)`:将元素推入此列表所表示的堆栈。
* `public boolean isEmpty()`:如果列表不包含元素,则返回true。

** - ArraryList :
实现类介绍:public class ArrayListextends AbstractListimplements List, RandomAccess, Cloneable, Serializable
1>可调整大小的数组的实现List接口。 实现所有可选列表操作,并允许所有元素,包括null
2>*请注意,此实现不同步 * 类外部同步/包装 List list = Collections.synchronizedList(new ArrayList(…));
3> The iterators returned by this class’s个 iterator和listIterator方法是快速失败的 :如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove种或add方法,迭代器都将抛出一个ConcurrentModificationException 。 因此,面对并发修改,迭代器将快速而干净地失败,而不是在未来未确定的时间冒着任意的非确定性行为。
请注意,迭代器的故障快速行为无法保证,因为一般来说,在不同步并发修改的情况下,无法做出任何硬性保证。 失败快速迭代器尽力投入ConcurrentModificationException 。 因此,编写依赖于此异常的程序的正确性将是错误的:迭代器的故障快速行为应仅用于检测错误。

ArrayList和LinkedList的区别和相同点:
相同点:1.继承关系:List接口下的实现类,具有List提供的方法
2.有序性:数据按照插入时有序
3.重复性:集合中的元素可以重复
4.null值:都可以存储Null值
5.安全性:都是非线程安全的集合
不同点:1.数据结构: LinkedList是双向链表 ArrayList是数组
2.特有方法:例如:addFirst addLast 实现了Deque;
3.效率:ArrayList查询效率高 Linked List添加删除效率高
ArrayList查询元素的效率趋近O(1) Linked List增加的元素趋近于O(1)
应用场景不同: Array List在查询较多的情况下优先考虑 LinkedList在添加、修改较多的情况下优先考虑

Set : 特点是元素无序,元素不可重复,没有索引 有两个实现类
      接口介绍:public interface Set<E>extends Collection<E>

1> 不包含重复元素的集合。 更正式地,集合不包含一对元素e1和e2 ,使得e1.equals(e2) ,并且最多一个空元素。 正如其名称所暗示的那样,这个接口模拟了数学集抽象。
2>尝试对不符合条件的元素的操作,其完成不会导致不合格元素插入到集合中,可能会导致异常,或者可能会成功执行该选项。 此异常在此接口的规范中标记为“可选”。
3>Set集合取出元素的方式可以采用:迭代器、增强for。

** - HashSet :
实现类介绍:public class HashSetextends AbstractSetimplements Set, Cloneable, Serializable
1> 此类实现Set接口,由哈希表(实际为HashMap实例)支持。 对集合的迭代次序不作任何保证; 特别是,它不能保证订单在一段时间内保持不变。 这个类允许null元素。
哈希表:在JDK1.8
之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

eq:简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的

    @Override
    public boolean equals(Object o) {
        Student personOne = (Student) obj;
        return this.age==personOne.age&&this.equals(((PersonOne) obj).name);
    }
    @Override
    public int hashCode() {
        return name.hashCode+age*38;
    }
  • LinkedHashSet :
    实现类介绍:public class LinkedHashSetextends HashSetimplements Set, Cloneable, Serializable
    1> 哈希表和链表实现了Set接口,具有可预测的迭代次序。这种实现不同于HashSet,它维持于所有条目的运行双向链表。 该链表定义了迭代排序,它是将元素插入集合(插入顺序 ) 的顺序 。 请注意,如果一个元件被重新插入到组插入顺序不受影响 。
    2>LinkedHashSet的迭代需要与集合的大小成比例的时间,无论其容量如何。 HashSet的迭代可能更昂贵,需要与其容量成比例的时间。
    3>链接哈希集具有影响其性能的两个参数: 初始容量和负载因子 。 它们的定义精确到HashSet 。
    4>请注意,此实现不同步类外部同步 Set s = Collections.synchronizedSet(new LinkedHashSet(…));
    5>快速失败
public class LinkedHashSetDemo {
    public static void main(String[] args) {
        Set<String> set = new LinkedHashSet<String>();
        set.add("bbb");
        set.add("aaa");
        set.add("abc");
        set.add("bbc");
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}
结果:
  bbb
  aaa
  abc
  bbc

** - TreeSet :
实现类介绍:public class TreeSetextends AbstractSetimplements NavigableSet, Cloneable, Serializable
1>此实现提供了基本的操作(保证的log(n)时间成本add , remove和contains )。
2>快速失败
3> 请注意,此实现不同步类外部同步SortedSet s = Collections.synchronizedSortedSet(new TreeSet(…));

 Iterator iterator =ts .iterator();
        while (iterator .hasNext() ){
            Chilgren c=(Chilgren)iterator .next();
            System.out.println(c.getName() +" "+c.getAge() );
        }/*返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。eeewwwd*/
       Chilgren C= ts .ceiling(new Chilgren("四个",16) ) ;
        System.out.println(C.getName() +" "+C .getAge() );

Collections

2.1 常用功能

  • java.utils.Collections是集合工具类,用来对集合进行操作。部分方法如下:
    • public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。
  • public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
  • public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
  • public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。
public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        //原来写法
        //list.add(12);
        //list.add(14);
        //list.add(15);
        //list.add(1000);
        //采用工具类 完成 往集合中添加元素  
        Collections.addAll(list, 5, 222, 12);
        System.out.println(list);
        //排序方法 
        Collections.sort(list);
        System.out.println(list);
    }
}
结果:
[5, 222, 1, 2]
[1, 2, 5, 222]

Comparator比较器

我们还是先研究这个方法
public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。

public class CollectionsDemo2 {
    public static void main(String[] args) {
        ArrayList<String>  list = new ArrayList<String>();
        list.add("cba");
        list.add("aba");
        list.add("sba");
        list.add("nba");
        //排序方法
        Collections.sort(list);
        System.out.println(list);
    }
}

我们使用的是默认的规则完成字符串的排序,那么默认规则是怎么定义出来的呢?
说到排序了,简单的说就是两个对象之间比较大小,那么在JAVA中提供了两种比较实现的方式,一种是比较死板的采用java.lang.Comparable接口去实现,一种是灵活的当我需要做排序的时候在去选择的java.util.Comparator接口完成。
那么我们采用的public static <T> void sort(List<T> list)这个方法完成的排序,实际上要求了被排序的类型需要实现Comparable接口完成比较的功能,在String类型上如下:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {

String类实现了这个接口,并完成了比较规则的定义,但是这样就把这种规则写死了,那比如我想要字符串按照第一个字符降序排列,那么这样就要修改String的源代码,这是不可能的了,那么这个时候我们可以使用
public static <T> void sort(List<T> list,Comparator<? super T> )方法灵活的完成,这个里面就涉及到了Comparator这个接口,位于位于java.util包下,排序是comparator能实现的功能之一,该接口代表一个比较器,比较器具有可比性!顾名思义就是做排序的,通俗地讲需要比较两个对象谁排在前谁排在后,那么比较的方法就是:

  • public int compare(String o1, String o2):比较其两个参数的顺序。

    两个对象比较的结果有三种:大于,等于,小于。

    如果要按照升序排序,
    则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)
    如果要按照降序排序
    则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)
    操作如下:

public class CollectionsDemo3 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("cba");
        list.add("aba");
        list.add("sba");
        list.add("nba");
        //排序方法  按照第一个单词的降序
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.charAt(0) - o1.charAt(0);
            }
        });
        System.out.println(list);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值