JAVA集合和guava集合使用和原理解析

本文介绍了Java集合框架和Guava集合框架,包括总体介绍、接口及类详解。Java集合分为List、Set、Queue、Map四大接口体系,而Guava提供了BiMap、Multiset等独特集合类型。文章详细解析了如ArrayList、HashMap、HashSet、BitSet等类的原理,以及Guava的Multimaps和Table。此外,还讨论了常用API、集合操作如交集、差集、并集、排序、转换等,并提到了红黑树的概念。
摘要由CSDN通过智能技术生成

 

一:总体介绍:

Java集合框架介绍

 集合可以看作是一种容器,用来存储对象信息。所有集合类都位于java.util包下,但支持多线程的集合类位于java.util.concurrent包下。

Java集合类主要由两个根接口Collection和Map派生出来的,Collection派生出了三个子接口:List、Set、Queue(Java5新增的队列),因此Java集合大致也可分成List、Set、Queue、Map四种接口体系,(注意:Map不是Collection的子接口)。

其中List代表了有序可重复集合,可直接根据元素的索引来访问;Set代表无序不可重复集合,只能根据元素本身来访问;Queue是队列集合;Map代表的是存储key-value对的集合,可根据元素的key来访问value。

 Java集合和数组的区别:                                       

  1. 已定义集合的大小可变,而已定义的数组大小不可变(注意:集合内部实现机制也用到了对象数组,只是通过数组的复制或链式存储的方式使其从外部看起来是可变的,而其本身并未颠覆数组大小不可变这一观点)
  2. 数组可以存储基本数据类型和引用类型,而集合只能存储引用类型,例如传入add方法中的int会被自动封装成Integer类型
  3. 数组只能存储相同类型的数据,而集合如未确定泛型的具体类型,则可存储任意引用类型数据

Guava集合框架介绍

 

Guava 是一款 Google 开源工具类,包含许多 Google 内部 Java 项目依赖的核心类。Guava 扩展 Java 基础类工程,比如集合,并发等,也增加一些其他强大功能,比如缓存,限流等功能。另外 Guava 推出一些类,如 Optional,甚至被 Java 开发者学习,后续增加到 JDK 中。Guava 创造很多 JDK 没有,但是我们日常却明显有用的新集合类型。这些新类型使用 JDK 集合接口规范,所以使用方法与 JDK 集合框架差不多,并没有增加很多使用难度。

 

集合接口 属于JDK还是Guava 对应的Guava工具类
Collection JDK Collections2:不要和java.util.Collections混淆
List JDK Lists
Set JDK Sets
SortedSet JDK Sets
Map JDK Maps
SortedMap JDK Maps
Queue JDK Queues
Multiset Guava Multisets
Multimap Guava Multimaps
BiMap Guava Maps
Table Guava Tables


二:接口及类详解【JAVA】

Iterable<T> 接口

常用方法:

方法名或属性名称 描述 注意事项 备注
Iterator<T> iterator();
返回每个元素的迭代器
   
default void forEach(Consumer<? super T> action)

循环操作每个元素

 
 
default Spliterator<T> spliterator()

创建一个spliterator

 
   

重点方法介绍及代码示例

/**
 * iteable测试类
 */
public class TestItearble {
	// 返回迭代器,hasNext方法判断是否有下一个元素 next方法取下一个元素
    public static void testIterator(List<Integer> list) {
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
   
  // foreach 内部用的还是iterator
    public static void testForeach(Set<String> set) {
        set.forEach(System.out::println);
    }
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(4);
        testIterator(list);
        Set<String> set = new HashSet<>();
        set.add("one");
        set.add("three");
        set.add("four");
        set.add("one");
        testForeach(set);
    }


spliterator是java1.8新提出的能够进行并行遍历的迭代器.首先, iterator是专门用于迭代集合元素的方法,在List类中就有iterator()方法.集合通过调用Iterator方法,可以对该集合进行循环,效果就相当于是使用了for循环,但是iterator的好处就是不论是List,还是Map,都可以通过iterator进行遍历.但是,通过iterator和for循环一样,都是单线程的操作,Spliterator也用于遍历数据源中的元素,但它是为了并行执行而设计的。Java 8已经为集合框架中包含的所有数据结构提供了一个默认的Spliterator实现。集合实现了Spliterator接口,接口提供了一个spliterator方法。详解可见:https://blog.csdn.net/sl1992/article/details/100149187?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

public class TestSplitror {

    private static class Thread<T> extends java.lang.Thread {

        private final Spliterator<T> list;

        private Thread(Spliterator<T> list) {
            this.list = list;
        }

        @Override
        public void run() {
            list.forEachRemaining(System.out::println);
        }

    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 2000; i++) {
            list.add("split" + i);
        }
        // 拆分迭代器
        Spliterator<String> spliterator = list.spliterator();
        Spliterator<String> stringSpliterator = spliterator.trySplit();

        Thread<String> stringthread = new Thread<>(spliterator);
        Thread<String> stringthread1 = new Thread<>(stringSpliterator);
        stringthread.start();
        stringthread1.start();
        while (true) {
            if (stringthread.isAlive() || stringthread1.isAlive()) {
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
        System.out.println("main end");
    }

}

Collection<E> 接口

常用方法

方法名或属性名称 描述 注意事项 备注
int size();
返回集合的元素数量
如果元素数量超过Integer.MAX_VALUE返回Integer.MAX_VALUE.
 
boolean isEmpty();
返回集合是否没有元素
   
boolean contains(Object o);
如果集合有该元素返回true
ClassCastException 元素类型不相容
 
Object[] toArray();
返回一个装有改集合元素的数组
排序
<T> T[] toArray(T[] a)该方法可以对返回的数组类型进行精确控制。而非像toArray方法一样返回Object[]
boolean add(E e);
添加一个元素,添加成功返回true
 
 
boolean remove(Object o);
移除一个元素,移除成功返回true
 
 
boolean containsAll(Collection<?> c);
是否存在当前集合中的所有元素
 
 
boolean addAll(Collection<? extends E> c);
添加当前集合中的所有元素
 
 
boolean removeAll(Collection<?> c);
移除当前集合中的所有元素
 
 
default boolean removeIf(Predicate<? super E> filter)
根据给定的公式移除元素
 
 
default Stream<E> stream()
返回streeam流
   
default Stream<E> parallelStream()
返回并行stream流
   


重点方法介绍及代码示例

add() 向集合中添加一个元素。集合更改则添加成功返回true,如果该集合不允许重复并且已经包含指定的元素。返回false。部分子类的add方法可能会限制添加到集合中的元素类型,或者不会将NULL添加到集合中。
public class TestCollectionApi {

    public static void main(String[] args) {
        Collection set = new HashSet<>();
        boolean one = set.add("one");
        boolean one1 = set.add("one");
        System.out.println("set第一次添加add" + one);
        System.out.println("set第二次添加add" + one1);
        Collection list = new ArrayList<>();
        boolean one2 = list.add("list");
        boolean one3 = list.add("list");
        System.out.println("list第一次添加add" + one2);
        System.out.println("list第二次添加add" + one3);
    }

}
返回结果为:true false true true

List<E>接口

一个排序的集合(也被称作序列),接口使用者可以精确控制每个元素在集合中的插入位置,用户可以根据integer类型的索引访问和搜索集合中的元素。不像set,集合通常允许重复的元素,如果他们允许null元素存在的话,也可以存在重复的null。

 

方法名或属性名称 描述 注意事项 备注
default void replaceAll(UnaryOperator<E> operator)
将此列表中的每个元素替换为对该元素应用运算符的结果。    
default void sort(Comparator<? super E> c)
根据明确的比较器进行排序    
E get(int index);
返回该位置的元素    
E set(int index, E element);
用明确的元素替换明确位置的元素。    
void add(int index, E element);
插入元素到固定的位置,原该位置元素及后面的元素索引加一。    
E remove(int index);
移除具体位置的元素,后面的元素索引减一    
int indexOf(Object o);
返回该元素的索引位置或者返回-1(如果不存在)    
ListIterator<E> listIterator();
返回一个list迭代器
int lastIndexOf(Object o);返回最后一个该元素的索引位置或者-1(不存在)
 
List<E> subList(int fromIndex, int toIndex);
返回一个前闭后开的视图。    

重点方法介绍及代码示例

public class TestListApi {

    public static void main(String[] args) {
        List<String> list = new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.set(1, "d");
        System.out.println(list);
        list.add(1, "k");
        System.out.println(list);
        list.replaceAll(x -> {
            if (x.equals("a")) {
                return "tt";
            }
            return x;
        });
        System.out.println(list);
        list.sort(String::compareTo);
        System.out.println(list);
        List<String> list1 = list.subList(0, 2);
        list1.set(0, "kkkk");
        System.out.println(list);
    }
}
返回结果为:
[a, d, c]
[a, k, d, c]
[tt, k, d, c]
[c, d, k, tt]
[kkkk, d, k, tt]

Set<E>接口

 

 元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的)
 Set接口有两个实现类:HashSet(底层由HashMap实现),LinkedHashSet 
 SortedSet接口有一个实现类:TreeSet(底层由平衡二叉树实现)
 
 Set : 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。
 HashSet : 为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。
 TreeSet : 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。
 LinkedHashSet : 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。
方法名或属性名称 描述 注意事项 备注
boolean contains(Object o);
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值