首页 > 编程语言 > 详细

Java集合框架学习

时间:2021-09-24 17:07:47      阅读:51      评论:0      收藏:0      [点我收藏+]

技术分享图片

 

技术分享图片

 

 

 

 

 

 

学习总纲:

Java 集合框架提供了一组接口和类,以实现各种数据结构和算法。

Java集合框架提供了可以直接使用的各种数据结构和算法。这有两个主要优点:

  • 我们不需要手动编写代码来实现这些数据结构和算法。

  • 随着集合框架的高度优化,我们的代码将更加高效。

此外,集合框架允许我们对特定类型的数据使用特定的数据结构。例如,

  • 如果我们希望我们的数据是唯一的,那么我们可以使用集合框架提供的Set接口。

  • 要以键/值对的形式存储数据,可以使用Map接口。

  • ArrayList类提供可调整大小的数组的功能

〇-1、大树根之一:Collection

Collection 接口包括各种可用于对对象执行不同操作的方法。这些方法在其所有子接口中均可用。

  • add() - 将指定的元素插入到集合中
  • addAll() - 将指定集合的所有元素添加到集合中
  • size() - 返回集合的大小
  • remove() - 从集合中删除指定的元素
  • removeAll() - 从集合中删除指定集合的所有元素
  • iterator() - 返回一个迭代器以访问集合的元素
  • clear() - 删除集合中的所有元素

〇-2、大树根之二:Map

〇-3、大树根之三:Iterator

一、List路线

List接口是一个有序的集合,它允许我们像数组一样添加和删除元素

由于List是接口,因此无法从中创建对象。

为了使用List接口的功能,我们可以使用以下类:

  • 数组列表(ArrayList类)
  • 链表(LinkedList类)
  • 向量(vector类)
  • 堆栈(Stack类) 

技术分享图片 

 

首先,使用这些集合框架的声明一般为:

//List 的ArrayList 实现
List<String> list1 = new ArrayList<>();

// List 的LinkedList 实现
List<String> list2 = new LinkedList<>();

此时它是一个List对象了,有些ArrayList有但是List没有的属性和方法,它就不能再用了。而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性
为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?
问题就在于List有多个实现类,如 LinkedList或者Vector等等,现在你用的是ArrayList,也许哪一天你需要换成其它的实现类呢?,这时你只要改变这一行就行了:List list = new LinkedList();
其它使用了list地方的代码根本不需要改动。假设你开始用 ArrayList alist = new ArrayList(), 这下你有的改了,特别是如果你使用了 ArrayList特有的方法和属性。
如果没有特别需求的话,最好使用List list = new LinkedList(); ,便于程序代码的重构. 这就是面向接口编程的好处

Java ArrayList

ArrayList类是List接口的实现,允许我们创建可调整大小的数组

它的常用方法:

  1. 将元素添加到ArrayList

    study.list.add(28);
    study.list.add(3,21);//这种方法add,它的下标不能跳跃。
    animals.addAll(mammals);
  2. 初始化ArrayList:与数组不同,我们不能直接初始化数组列表

    import java.util.Arrays;//但是我们可以使用atList()来达到相同的目的
    ArrayList<String> animals = new ArrayList<>(Arrays.asList("Cat", "Cow", "Dog"));
  3. 访问ArrayList的元素

    1. 使用get()方法
      //从数组列表中获取元素
              String str = animals.get(0);
    2. 使用 iterator() 方法
      import java.util.Iterator;
      //创建一个Iterator对象
      Iterator<String> iterate = animals.iterator();
      
      //使用Iterator的方法访问元素
      while(iterate.hasNext()){
           System.out.print(iterate.next());
           System.out.print(", ");
      }
  4. 更改ArrayList元素

    //更改数组列表的元素
            animals.set(2, "Zebra");
  5. 删除ArrayList元素

    //从索引2中删除元素
            String str = animals.remove(2);
    // 删除所有元素
            animals.removeAll(animals);
    //删除所有元素
            animals.clear();
  6. 遍历 ArrayList

    1. 使用 for 循环
      for(int i = 0; i < animals.size(); i++) {
                  System.out.print(animals.get(i));
                  System.out.print(", ");
              }
    2. 使用forEach循环
      //使用forEach循环
              System.out.println("访问所有元素:  ");
              for(String animal : animals) {
                  System.out.print(animal);
                  System.out.print(", ");
              }
    3. 使用迭代器
  7. 获取ArrayList的长度

    //获取arrayList的大小
            System.out.println("arrayList的大小: " + animals.size());
  8. 对ArrayList的元素进行排序

    import java.util.Collections;
    //对数组列表进行排序
    Collections.sort(animals);
  9. 转换为 数组

    //将ArrayList转换成数组
            animals.toArray(arr);//arr为应该转化成的数组
  10. Array 转换为 ArrayList

    import java.util.Arrays;
    String[] arr = {"Dog", "Cat", "Horse"};
    ArrayList<String> animals = new ArrayList<>(Arrays.asList(arr));
  11. ArrayList 转换为 字符串

    String str = animals.toString();

 

LinkedList:见Queue

Stack:不推荐使用

 Java堆栈Stack类已经过时,Java官方推荐使用Deque替代Stack使用

Vector(向量)

Vector类是List接口的一个实现,它允许我们创建类似于ArrayList类的可调整大小的数组

由于向量(vector)不是线程安全的并且效率较低,因此建议使用ArrayList代替Vector

 

 

二、Queue路线

当我们要以先进先出(有输入输出次序)的方式存储和访问元素时,可以使用Queue接口

技术分享图片

 

技术分享图片

 

 

 

不知道为啥,队列这种集合好像很少被用到,可能是这种输入输出端受限的数据结构也可以用List实现。

 

1、PriorityQueue实现类

使用方法和队列一样,但是它对入队的元素有排序(大小根堆),是用数组存放的,但是逻辑上是有顺序的。

2、Deque接口

技术分享图片

 

在常规队列中,元素是从后面添加的,而从前面删除的。但是,在双端队列中,我们可以从前后插入和删除元素

双端队列作为堆栈数据结构

  • push() - 在双端队列的开头添加元素

  • pop() - 从双端队列的开头删除元素

 

  • peek() - 从双端队列的开头返回一个元素

1、LinkedList(链表)

技术分享图片

 

 

LinkedList的API
boolean       add(E object)
void          add(int location, E object)
boolean       addAll(Collection<? extends E> collection)
boolean       addAll(int location, Collection<? extends E> collection)
void          addFirst(E object)
void          addLast(E object)
void          clear()
Object        clone()
boolean       contains(Object object)
Iterator<E>   descendingIterator()
E             element()
E             get(int location)
E             getFirst()
E             getLast()
int           indexOf(Object object)
int           lastIndexOf(Object object)
ListIterator<E>     listIterator(int location)
boolean       offer(E o)
boolean       offerFirst(E e)
boolean       offerLast(E e)
E             peek()
E             peekFirst()
E             peekLast()
E             poll()
E             pollFirst()
E             pollLast()
E             pop()
void          push(E e)
E             remove()
E             remove(int location)
boolean       remove(Object object)
E             removeFirst()
boolean       removeFirstOccurrence(Object o)
E             removeLast()
boolean       removeLastOccurrence(Object o)
E             set(int location, E object)
int           size()
<T> T[]       toArray(T[] contents)
Object[]     toArray()

技术分享图片

 

 

2、ArrayDeque

在Java中,我们可以使用ArrayDeque该类使用数组来实现队列和双端队列数据结构

技术分享图片

 

技术分享图片

 

 

 

 

三、Set路线

Set接口允许我们将元素存储在不同的集合中,类似于数学中的集合。它不能有重复的元素

技术分享图片

 

Set集合运算

Java Set接口允许我们执行基本的数学集合运算,例如并集,交集和子集。

  • Union - 为了得到两个集合x和y的并集,我们可以使用x.addAll(y)

  • Intersection - 要获得两个集合x和y的交集,我们可以使用x.retainAll(y)

  • Subset - 要检查x是否是y的子集,我们可以使用y.containsAll(x)

 

HashSet 类

Java Collections框架的HashSet类提供了哈希表数据结构的功能。

//具有8个容量和0.75负载因子的HashSet
HashSet<Integer> numbers = new HashSet<>(8, 0.75);

也可以不传递参数初始化hashset,默认的容量为16,负载因子为0.75

 

访问HashSet元素

要访问哈希集合的元素,我们可以使用iterator()方法。为了使用此方法,我们必须导入java.util.Iterator包

// 调用iterator()方法
        Iterator<Integer> iterate = numbers.iterator();
        System.out.print("使用Iterator的HashSet: ");
        //访问元素
        while(iterate.hasNext()) {
            System.out.print(iterate.next());
            System.out.print(", ");
        }

 

集合的并交差

执行两个集合之间的并集,我们可以使用addAll()方法

numbers.addAll(evenNumbers);
//就是在一个集合中加入另一个集合,由于集合元素的唯一性,实现了并的功能

 

要执行两个集合之间的交集,我们可以使用retainAll()方法

 

//集合的交集,即保存与新set共有的元素
evenNumbers.retainAll(primeNumbers);

 

要计算两组之间的差集,我们可以使用removeAll()方法

//HashSet1和HashSet2之间的差集
   primeNumbers.removeAll(oddNumbers);

 

Set集合的子集

要检查一个集合是否是另一个集合的子集,我们可以使用containsAll()方法

//检查primeNumbers是否是numbers的子集
        boolean result = numbers.containsAll(primeNumbers);

 

为什么选择HashSet?

在Java中,如果我们必须随机访问元素,则通常使用HashSet。 这是因为哈希表中的元素是使用哈希码访问的。

元素的hashcode是唯一标识,它有助于标识散列表中的元素。

HashSet不能包含重复的元素。因此,每个散列集元素都有一个惟一的hashcode。

 

四、Map路线

Map接口允许元素以键/值对的形式存储。键是唯一的名称,可用于访问map中的特定元素。而且,每个键都有一个与之关联的值

Map接口维护3个不同的集合:

  • 键集

  • 值集

  • 键/值关联(Map集合)的集合。

因此,我们可以分别访问键,值和关联。

技术分享图片

 

//使用HashMap类创建Map
Map<Key, Value> numbers = new HashMap<>();

map方法

Map接口包括Collection接口的所有方法。这是因为Collection是Map的超级接口。

除了Collection接口中可用的方法之外,Map接口还包括以下方法:

  • put(K,V) - 将键K和值V的关联插入到map中。如果键已经存在,则新值将替换旧值。

  • putAll() - 将指定Map集合中的所有条目插入此Map集合中。

  • putIfAbsent(K,V) - 如果键K尚未与value关联,则插入关联V。

  • get(K) - 返回与指定键K关联的值。如果找不到该键,则返回null。

  • getOrDefault(K,defaultValue) - 返回与指定键K关联的值。如果找不到键,则返回defaultValue。

  • containsKey(K) - 检查指定的键K是否在map中。

  • containsValue(V) - 检查指定的值V是否存在于map中。

  • replace(K,V) - 将键K的值替换为新的指定值V。

  • replace(K,oldValue,newValue) - 仅当键K与值oldValue相关联时,才用新值newValue替换键K的值。

  • remove(K) - 从键K表示的Map中删除条目。

  • remove(K,V) - 从Map集合中删除键K与值V相关联的条目。。

  • keySet() -返回Map集合中存在的所有键的集合。

  • values() -返回一组包含在Map集合中的所有值。

  • entrySet() -返回map中存在的所有键/值映射的集合。

 

1、HashMap

//具有默认容量和负载因子的HashMap
HashMap<Key, Value> numbers1 = new HashMap<>();

访问HashMap元素

1.使用entrySet(),keySet()和values()

    • entrySet() -返回一组所有键/值映射的map

    • keySet() -返回map所有键的集合

    • values() -返回map所有值的集合

2.使用get()和getOrDefault()

    • get() - 返回与指定键关联的值。如果找不到键,则返回null。

    • getOrDefault() - 返回与指定键关联的值。如果找不到键,则返回指定的默认值。

替换元素

    • replace(key, value) - 将key的值替换为value

    • replace(key, old, new) - 仅当old值已与指定键key关联时,才用new值替换old值

    • replaceAll(function) - 用指定函数的结果替换映射的每个值

重新计算值

1.使用compute()方法

    • compute() - 使用指定的函数计算新值。然后将计算值与指定的键相关联。

    • computeIfAbsent() - 如果指定的键没有映射到任何值,该方法将使用指定的函数计算一个新值。然后将新值与键关联。

    • computeIfPresent() -如果指定的键已经映射到任何值,此方法将使用指定的函数计算一个新值。然后将新值与键关联。

2.使用merge()方法

  如果指定的键尚未关联,则merge()方法将指定的值与指定的键关联。

  但是,如果指定的键已经与一个值关联,它将把新的指定值与现有的旧值合并

 

2、LinkedHashMap

  LinkedHashMap类提供了Map接口的哈希表和链表实现。

  LinkedHashMap继承了HashMap类,以将其条目存储在哈希表中。它在内部在所有条目之间维护一个双链列表,以对条目进行排序。

技术分享图片

 

技术分享图片

 

 

3、ConcurrentHashMap

ConcurrentHashMap类提供了线程安全的映射。 也就是说,多个线程可以一次访问该映射,而不会影响映射中条目的一致性。

技术分享图片

 

ConcurrentHashMap和HashMap 的区别

以下是ConcurrentHashMap和HashMap之间的一些区别,

  • ConcurrentHashMap是线程安全的集合。也就是说,多个线程可以同时访问和修改它。

  • ConcurrentHashMap提供用于批量操作的方法,例如forEach(),search()和reduce()。

为什么选择ConcurrentHashMap?

  • ConcurrentHashMap类允许多个线程修改操作并发进行。

  • 默认情况下,并发哈希映射分为16段。这就是为什么允许16个线程同时修改映射的原因。但是,一次可以访问任意数量的线程。

  • 如果指定的键已经存在,则putIfAbsent()方法将不会覆盖映射中的条目。

 

 

五、Iterator路线

Iterator即迭代器,实现透明的遍历访问,即不论集合的内部组织形式是何种样子的,只要实现了Iterator接口就能方便的实现遍历。

技术分享图片

 

迭代器的方法

Iterator接口提供了4种方法,可用于对集合元素执行各种操作。常用的就是next和hasNext。

  • hasNext() - 如果集合中存在元素,则返回true

  • next() - 返回集合的下一个元素

  • remove() -删除next()返回的最后一个元素

  • forEachRemaining() - 对集合的每个剩余元素执行指定的操作

//创建Iterator的实例
        Iterator<Integer> iterate = numbers.iterator();

 

ListIterator 接口

ListIterator提供了访问列表元素的功能。

它是双向的。 这意味着它允许我们在两个方向上迭代列表的元素。

ListIterator的方法

ListIterator接口提供了可用于对列表元素执行各种操作的方法。

  • hasNext() - 如果列表中存在元素,则返回true

  • next() - 返回列表的下一个元素

  • nextIndex() - 返回next()方法将返回的元素的索引

  • previous() - 返回列表的前一个元素

  • previousIndex()- 返回previous()方法将返回的元素的索引

  • remove()- 删除由next()或previous()返回的元素

  • set() - 将next()或previous()返回的元素替换为指定的元素

 

六、java集合框架提供的算法

  1.使用sort()排序

  // 使用sort()方法
        Collections.sort(numbers);

  2.使用shuffle进行洗牌

//使用shuffle()方法
        Collections.shuffle(numbers);

3.常规数据处理

在Java中,集合框架提供了可用于处理数据的不同方法。

    • reverse() - 反转元素的顺序

    • fill() - 用指定的值替换集合中的每个元素

    • copy() - 创建从指定源到目标的元素副本

    • swap() - 交换集合中两个元素的位置

    • addAll() - 将集合的所有元素添加到其他集合

  4.使用binarySearch()搜索

 // 使用 binarySearch(),返回在集合中的位置,在执行binarySearch()方法之前,应对集合进行排序。
        int pos = Collections.binarySearch(numbers, 3);

  5.组合

    • frequency() - 返回元素在集合中存在的次数计数

    • disjoint() - 检查两个集合是否包含一些公共元素

  6.寻找最大和最小元素

    Java集合框架的min()和max()方法分别用于查找最小和最大元素。  

 

Java集合框架学习

原文:https://www.cnblogs.com/lison-qlq/p/15302938.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!