集合(java)

一、集合概述

集合与数组:

数组(可以存储基本类型数据)是用来存储数据的一种容器,能够快速的进行存取,但是只能存储同一类型数据,而且需要连续的内存空间存储,长度一旦定义就不能再改变,但是我们需要存储的数据的数量是变化的,结构是多样的,一种数组结构显然不能满足所有的需求,于是就有了各种各样的数据结构,Java中对于各种数据结构的实现,就是我们用到的集合。

二、集合体系概述

Java的集合框架是由很多接口、抽象类、具体类组成的,都位于java.util包中。

e90232603c654b0aa09f7fbf100c3b6c.png

 

三、Collection 接口

 Collection接口作为单列集合中顶级接口,里面定义了单列集合共有的方法,方法以增、删、改、查、判断、转换为主,其子接口Set和List分别定义了存储方式。

● List中的数据对象有顺序且可以重复。

● Set中的数据对象没有顺序且不可以重复。

注意:

集合是容器,可以存储不同的数据,严格上讲集合中是可以存储任何类型的(只能存储引用类型),但是我们一般建议在集合中存储同类型数据。

补充:

Collection<E>,ArrayList<E>后面<E>是jdk5之后的语法---泛型,可以通过泛型语法,为集合设置一个类型,这样就只能存储设置的数据类型。

Collection接口中定义了一些集合中的共有方法:

常用方法:

①boolean add(Object element);

  • 向集合末尾添加元素

②addAll(Collection coll);

  • 把一个集合添加到另一个集合

③void clear();

  • 清空集合中的元素,不是将集合对象变为null,而是将集合对象变为一个空集合

④int size();

  • 获取集合中实际存在的元素的个数

⑤boolean isEmpty();

  • 判断集合中元素的个数是否为空

⑥boolean remove(Object element);

  • 删除指定元素,成功返回true,没有返回false

⑦boolean retainAll(Collection c);

  • 求交集,集合数据发生变化返回true,不变返回false

案例:

import java.util.ArrayList;
import java.util.Collection;
​
public class CollectionDmeo {
     public static void main(String[] args) {   
         Collection<String> c = new ArrayList<>();
                    c.add("a");
                    c.add("b");
                    c.add("c");
                    c.add("d");
        Collection<String> c1 = new ArrayList<>();
                    c1.add("a");
                    c1.add("b");
                    c1.add("c");
                    //向集合末尾添加元素
                    c1.add("d");
         
                    //把一个集合添加到另一个集合
                    c1.addAll(c);
                    //清空集合中的元素
                    c.clear();
                    //比较两个集合中的内容是否相等
                    System.out.println(c.equals(c1));
                    //判断集合中元素的个数是否为空           
                    System.out.println(c.isEmpty());
                    //删除指定元素,成功返回true,没有返回false
                    System.out.println(c.remove("h"));
                    //在c中保留c1中交集的元素,发生变化返回true,没有变化返回false
                    System.out.println(c.retainAll(c1));
                    //数组长度length,字符串长度length(),集合长度size() 
                    System.out.println(c.size());
     }
}

三、List 接口及实现类

List继承了Collection接口,有三个实现的类

1.ArrayList :底层是通过数组实现的,是可以边长的,查询快,中间增删慢(因为后面的元素位置要发生改变)。

  • ArrayList的常用方法 :

①add(int index, E element)

  • 在指定位置添加元素

②get(int index)

  • 返回列表中指定位置

③remove(int index)

  • 删除并返回指定位置元素

④removeRange(int fromIndex, int toIndex)

  • 删除指定区间的元素(子类继承使用)

⑤set(int index, E element)

  • 将索引位置元素替换为元素element并返回被替换的元素

案例:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
​
public class ArrayListDemo1 {   
     public static void main(String[] args) {    
          /*
             add();向集合中添加元素时,底层会默认创建一个长度为10的Object类型数组,
                   当数组装满时,再次添加元素,会创建一个原来数组长度1.5倍的新数组,
                   将原数组内容复制过来,最后将新数组地址赋给底层的数组。
             public boolean add(E e) {
                    ensureCapacityInternal(size + 1);  // Increments modCount!!
                    elementData[size++] = e;
                    return true;
             }
             if (minCapacity - elementData.length > 0)
                   grow(minCapacity);底层扩展的方法
           */
          //List<String> list = new ArrayList<>();
          ArrayList<String> list = new ArrayList<>();
                            list.add("a");
                            list.add("b");
                            list.add("c");
                            list.add("d");
                            list.add("d");
                            list.add("d");
                            list.add("d");
                            
                            list.add(0, "X");//向指定下标位置上添加元素
                            System.out.println(list.get(11));//elementData[index];
                            System.out.println(list.remove(0));//删除并返回指定位置的元素
                            list.set(2, "K");//替换指定位置的元素
                            System.out.println(list.size());//返回集合中实际存储的元素个数            
     }
}

2.LinkedList: 底层是链表实现查询慢(必须从头/尾开始查找,直到找到),中间增删快,只需要改变后继节点位置。

  • LinkedList的常用方法:

①add(int index,Object element)

  • 在指定位置添加元素

②addFirist(Object element)

  • 将指定元素添加到此列表的开头

③addLast(Object element)

  • 将指定元素添加到此列表的末尾

④get(int index)

  • 返回此列表指定位置的元素

⑤removeFirst()

  • 删除并返回此列表的第一个元素

⑥removeLast()

  • 删除并返回此列表的最后一个元素

⑦remove(int index)

  • 删除并返回指定位置的元素

⑧getFirst()

  • 返回此列表的第一个元素

⑨getLast()

  • 返回此列表的最后一个元素

案例:

import java.util.LinkedList;
​
public class LinkedListDemo {
     public static void main(String[] args) {
        
         LinkedList<String> llist  = new LinkedList<>();
                            llist.add("a");//向链表中添加元素
                            llist.add("b");
                            llist.add("c");
                            llist.add("d");
                            llist.add("e");
                            //要找的元素位置小于size/2,从头结点开始查找,否则从尾结点开始查找
                            System.out.println(llist.get(3));
                            
                            llist.addFirst("X");
                            llist.addLast("Y");
                            System.out.println(llist.removeFirst());
                            System.out.println(llist.removeLast());                     
               System.out.println(llist);                       
     }
}

3.Vector :底层是数组实现,线程安全的。

案例:

import java.util.Vector;
​
public class VectorDemo {   
    public static void main(String[] args) {
        /*
         *  底层也是数组实现,但是是线程安全的
         */
        Vector<String> v = new Vector<>();
                     v.add("a");
                     v.add("b");
                     v.add("c");
                     v.add("d");
                     v.add("a");
    }
}

四、遍历List的三种方式

方式一:for循环遍历:遍历集合时,可以从中删除元素

注意: 删除元素后,元素向前移动,索引++,可能会出现错漏问题

import java.util.ArrayList;
​
public class ListDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
                    list.add("a");
                    list.add("b");
                    list.add("c");
                    list.add("d");
        for(int i = 0; i < a1.size();i++){
            System.out.println(a1.get(i));
        }
    }
}

方式二:增强for循环的遍历:在遍历的过程中不能删除元素 ,

如果删除会抛出ConcurrentModificationException(并发修改异常)

import java.util.ArrayList;
​
public class ArrayListDemo {    
     public static void main(String[] args) {
          ArrayList<String> list = new ArrayList<>();
                            list.add("a");
                            list.add("b");
                            list.add("c");
                            list.add("d");
              for(String s : list){
                    System.out.println(s);
              }
    }
}

方式三:迭代器遍历(Iterator)

import java.util.ArrayList;
import java.util.ListIterator;
​
public class ArrayListDemo {
     public static void main(String[] args) {    
          ArrayList<String> list = new ArrayList<>();
                            list.add("a");
                            list.add("b");
                            list.add("c");
                            list.add("d");
                            list.add("d");
                            list.add("d");
                            list.add("d");
                            list.add("d");
                            list.add("d");
                            list.add("d");
          /*
              迭代器遍历List集合2
              针对List接口下的集合类还提供listIterator()
           */
          //从指定的位置开始遍历
          ListIterator<String> it =  list.listIterator(2);
                     while(it.hasNext()){
                        String e = it.next();   
                         System.out.println(e);
          }
          //从指定的位置开始遍历(逆序遍历)                  
          ListIterator<String> it =  list.listIterator(list.size());
                             while(it.hasPrevious()){
                                String e = it.previous();   
                                 System.out.println(e);
          } 
    }
}

五、Set 接口

Set接口继承了Collection接口,Set中所存储的元素是不重复的,但是是无序的,Set中的元素是没有索引的

Set接口有两个实现类:

1.HashSet

HashSet 存储的元素顺序不固定

底层数据结构:哈希表+链表,哈希表依赖于哈希值存储

案例:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.TreeSet;
​
public class HashSetDemo {
​
     public static void main(String[] args) {
        /*
            无序且不重复的集合
            public HashSet() {
                map = new HashMap<>(); 底层使用的是HashMap实现的.
            }
         */
         HashSet<String> set = new HashSet<>();
                         set.add("a");
                         set.add("b");
                         set.add("z");
                         set.add("x");
                         set.add("x");
                         set.add("x");
              System.out.println(set);
              
              ArrayList<String> list = new ArrayList<>();
                 
                  list.add("d");
                  list.add("d");
                  list.add("a");
                  list.add("d");
                  list.add("x");
                  list.add("b");
                  list.add("c");
                 HashSet<String> set1 = new HashSet<>(list);
                 System.out.println(set1);
                 
                 TreeSet<String> set2 = new TreeSet<>(list);
                 System.out.println(set2);
                 
    }
}

2.TreeSet

可以给Set集合中的元素进行指定方式的排序,存储的对象必须实现Comparable接口。

底层数据结构:二叉树(红黑树是一种自平衡的二叉树)

案例:

public class Car implements Comparable<Car>{    
     private int no;
     private String name;
    
    public Car(int no, String name) {
        super();
        this.no = no;
        this.name = name;
    }
​
    @Override
    public int compareTo(Car o) {
     
        return this.no-o.no;
    }
​
    @Override
    public String toString() {
        return "Car [no=" + no + ", name=" + name + "]";
    } 
}
import java.util.TreeSet;
​
public class TreeSetDemo {
​
     public static void main(String[] args) {
        /*
           有序(可以根据元素自然顺序排序) 且 不能存储重复元素 
           public TreeSet() {
                this(new TreeMap<E,Object>());
           }
         */
         TreeSet<String> set = new TreeSet<>();
                         set.add("c");
                         set.add("b");
                         set.add("z");
                         set.add("a");
                         set.add("x");
                         set.add("x");
              System.out.println(set);
              
              
              Car car1 = new Car(1,"baoma1");
              Car car2 = new Car(2,"baoma2");
              Car car3 = new Car(3,"baom3");
              TreeSet<Car> carset = new TreeSet<>();
              carset.add(car1);
              carset.add(car3);
              carset.add(car2);
              System.out.println(carset);
    }
}

六、Set 接口集合迭代

遍历方式 :

方式一:增强for循环

方式二:迭代器遍历

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chen☆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值