Java 集合

2021-11-21  本文已影响0人  Java慈祥

Java 集合是一个常用的技术 ,无论是在: 开发使用,还是面试总是高频的提及到~

Java 集合

集合和数组:

Java 集合框架概述

Java 集合可分为 Collection 和 Map 两种体系

Collection接口: 单列数据,定义了存取一组对象的方法的集合

Map接口:双列数据,保存具有映射关系 key-value 的集合

Collection 接口:

2021042520100832

简介

Collection集合主要有List和Set两大接口 不常用的 Queue接口

List 接口

Set 接口

Collection接口的常用方法:

JDK不提供此接口的任何直接实现,而是提供更具体的子接口:set list 都默认继承了Collection 的方法();

boolean     .add( object );             //在列表 末尾添元素 和数组一样 起始索引位置从 0 开使,可储存null; 数值类型会自动装箱;
void        .add( int,object );         //指定索引位置添加元素 但 不可指定 在超过目前 集合长度;
void        .forEach(System.out::print);//jdk8 新特性;一种循环遍历;  
void        .clear();                   //清空集合;
int         .size();                    //返回集合元素个数; 
boolean     .contains( object );        //判断集合在是否存在指定元素; ture/flase; 底层相当于是调 equls();比,String类重写了所以比较的是值;
                                        //没重写当然就是比较地址咯;
boolean     .containAll( Collection );  //判断参数是个集合,判断参数集合自己有没有,都有就true 一个没有就false
boolean     .equals( Coll... );         //想要返回 true,需要当前集合元素 和 参数集合元素值都相同 地址 ;根据new ArrayList 或其它集合/其顺序也要相同;
Object      .get( int );                //返回指定索引的元素;( 注意这是Object 类型需要类型转换 );
List        .sublist(int1,int2);        //返回集合 1-2 位置的子集合;
Object      .set(int,Object);           //设置指定 int 位置的元素;


注意不可以在,集合进行循环遍历的时候移除元素!   因为集合长度发送改变,循环遍历报错!
Object      .remove( int );             //删除指定下标中的元素; 返回删除的元素;
boolean     .remove( object/int );      //移除集合中指定元素; true移除成功 false移除失败:不存在要移除元素; 
                                        //虽然数值类型会装箱,int下标删除了..需要确保下标存在
boolean     .removeAll( Collection );   //从集合中移除指定: 一个集合元素; 两个集合A B, A.removeAll(B); //把A B集合中一样的元素移除掉了(交集);

正确的删除需要使用:Iterator对象~
Iterator    .iterator();                //返回一个 Iterator对象; 

数组集合相互转换
Object[]    .toArray();                 //可以将集合返回一个 Object[] 数组;
集合        Arrays.aslist( 数组 );       //Arrays类的静态方法: 将数组转换成集合;

List 接口

Arraylist

Arraylist: 对数组进行封装,实现长度可变的数组(根据增删自动改变元素在集合中位置)

基本使用:

public void jh(){
    /** 创建集合对象 */
    //      Collection coll = new ArrayList();
    ArrayList arrayList = new ArrayList();      //List集合存储Object类型元素,支持重复元素!
    arrayList.add(1);
    arrayList.add(2);
    arrayList.add(2);
    arrayList.add(3);
    arrayList.add("2");
    arrayList.add(null);                        //可以存储null
    System.out.println("arrayList集合遍历:");
    for (Object o : arrayList) {
        System.out.println(o);
    }

    /** 常用方法 */
    //contains(Object obj):判断当前集合中是否包含obj   :判断时会调用obj对象所在类的equals(),自定义对象需要重写equals
    System.out.println("arrayList集合是否存在 1:"+arrayList.contains(1));

    //containsAll(Collection coll1) 判断形参coll1中的所有元素是否都存在于当前集合中
    ArrayList arrayList2 = new ArrayList();
    arrayList2.add(1);
    arrayList2.add(2);
    System.out.println("arrayList集合是否存在 arrayList2的所有元素:"+arrayList.containsAll(arrayList2));

    //retainAll(Collection coll1):交集:获取当前集合和coll1集合的交集,并返回给当前集合
    //        arrayList.retainAll(arrayList2);
    //        System.out.println("retainAll(Collection coll1):交集:获取当前集合和coll1集合的交集,并返回给当前集合");
    //        for (Object o : arrayList) {
    //            System.out.println(o);
    //        }

    /** 注释上面: retainAll() 让两个集合元素 A.retainAll(B) A集合只保留B 交集共同的数据了~ */
    //remove(Object obj):从当前集合中移除obj元素
    //removeAll(Collection coll1):差集:从当前集合中移除coll1中所有的元素
    arrayList.removeAll(arrayList2);
    System.out.println("removeAll(Collection coll1):差集:从当前集合中移除coll1中所有的元素");
    for (Object o : arrayList) {
        System.out.println(o);
    }

    /** 数组 ———》List集合 */
    System.out.println("使用: Arrays. asList(array) 进行转换");
    List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
    System.out.println(list);

    /** List集合 ———》数组 */
    System.out.println("使用: List 自带的 toArray() 方法");
    Object[] objects = list.toArray();
    for (Object obj : objects) {
        if(obj instanceof String)           // 对象 instanceof 类型  比较对象是否属于改类型~
            System.out.print(obj+" ");
    }
}

LinkedList

LinkedList:采用双向链表存储方式

LinkedList 新增方法

void    .addFist( object );         //在集合 首部 添加元素 (索引0);
void    .addLast( object );         //在集合 末尾 添加元素;
Object  .getFist(  );               //返回 第一元素;
Object  .getLast(  );               //返回 最后一个元素; 
Object  .removrFist(  );            //删除 并 返回第一个元素;
Object  .removeLast(  );            //删除 并 返回最后一个元素;    

Vector

Vector 读:歪课特 远古代码,jdk1.0就有的

ArrayList/LinkedList/vector的异同?

ArrayList和LinkedList的异同

ArrayList和Vector的异同:

Set 接口

简介:

Set接口实现 Collection接口

HashSet

LinkedHashSet: 作为HashSet子类,遍历器内部数据时,可以按照添加的顺序遍历

ThreeSet

向TreeSet添加的数据,要求是相同的类型的

List数据去重

五种有效方法:

  1. [方案一:借助HashSet的特性进行去重]
  2. [方案二 : 利用set集合特性保持顺序一致去重] TreeSet LinkedHashSet
  3. [方案三 : 使用list自身方法remove()–>不推荐] 循环遍历判断,remove()
  4. [方案四 : 使用Java8特性去重]
/** 方案一 */
@org.junit.Test
    public  void distinct() {
    List<String> lists = Arrays.asList(new String[]{"AA", "BB", "CC","CC"});
    HashSet<String> sets = new HashSet<>();
    for (String s : lists) {
        sets.add(s);
    }
    System.out.println("去重后的Set集合: "+sets);
}

@org.junit.Test
    /** 方案二 */
    public  void distinct2() {
    List<String> lists = Arrays.asList(new String[]{"AA", "BB", "CC","CC"});
    //方式一
    List<String> listNew = new ArrayList<String>(new TreeSet<String>(lists));
    System.out.println("TreeSet"+listNew);
    //方式二
    List<String> listNew2 = new ArrayList<String>(new LinkedHashSet<String>(lists));
    System.out.println("LinkedHashSet"+listNew);
}

@org.junit.Test
    /** 方案四 */
    public  void distinct4() {
    List<String> lists = Arrays.asList(new String[]{"AA", "BB", "CC","CC"});
    List<String> myList = lists.stream().distinct().collect(Collectors.toList());
    System.out.println("JDK8.0新特性:"+myList);
}

Iterator 迭代器接口

Iterator 中:迭代器 读:艾特瑞特~

可以通过,Collection类的 .iterator() 方法返回一个 Iterator迭代器对象

Iterator接口的方法

boolean hasNext();  //判断是否 存在下一个可访问的元素;
Object  next();     //返回要访问的下一个元素;
void    remove();   //移除当前的集合元素可保证从源集合中安全地删除对象;  注意(图:Iterator移除)

若不调用,且下一条记录无效直接调用 i.next()会抛出 NoSuchElementException异常。

202104111540176

Iterator 仅用于遍历集合

边遍历边修改 集合 的唯一正确方式是使用 Iterator.remove() 方法,如下:

Iterator<Integer> it = list.iterator();
while(it.hasNext()){
   *// do something*
   it.remove();
}

一种最常见的错误代码如下:

for(Integer i : list){
   list.remove(i)
}

Map 接口:

20210425201023880

简介

双列集合,存储一对 key-value 数据---》

HashMap:作为Map的主要实现类;线程不安全的,效率高;允许存储null的key和value

TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序 底层使用红黑树

Hashtable:作为古老的实现类

实现类有:

Map常用方法:

Object  .put(Object key,Object value);  //以 键值对 方式存储  注意(键 唯一 值 可以重复 //相同的键 后面的替代前面的 键值对 元素)    
Object  .get(key);                      //根据键 返回对应的值对象不存在对应键 返回 null;
Object  .remove(key);                   //根据键 删除指定 键值对 对象
int     .size();                        //返回元素个数
boolean .containsKey( object key );     //判断 是否存在 指定键值对 对象;
boolean .isEmpty();                     //判断 是否存在 键值对 对象
void    .clear();                       //清空该集合所有 元素;
Set     .keySet();                      //返回 键的集合 Set类型集合;    set是Collection 的实现类, 通过 .iterator(); 方法返回一个Iterator对象,进行遍历!
Collection  .values();                  //返回 值的集合 collection 类型集合;

实例:

@Test
public void mapTest(){
    Map map = new HashMap();       //只能存储 K 唯一, 值可以重复的元素,重复的key 会替代之前的数据!
    map.put(1, "AA");
    map.put(1, "AA");
    map.put(1, "BB");
    map.put(2, "AA");
    map.put(2, "BB");
    map.put(3, "CC");

    System.out.println("遍历所有的key-value");
    System.out.println("方式一: entrySet()");
    Set entrySet = map.entrySet();                  //获取所有的: entrySet()方法返回一个实现Map.Entry接口的对象集合
    Iterator iterator1 = entrySet.iterator();       //set 属于 collection.iterator(); 获取迭代器!
    while (iterator1.hasNext()){
        Object obj = iterator1.next();
        Map.Entry entry = (Map.Entry) obj;
        System.out.println(entry.getKey() + "---->" + entry.getValue());
    }
    System.out.println();
    System.out.println("方式二: 迭代器");
    //方式二:
    Set keySet = map.keySet();
    Iterator iterator2 = keySet.iterator();
    while(iterator2.hasNext()){
        Object key = iterator2.next();
        Object value = map.get(key);
        System.out.println(key + "=====" + value);

    }
    System.out.println();
    System.out.println("方式三: 通过ForEach循环进行遍历: 此数省略~");
    System.out.println();
    System.out.println("方式四: 通过Java8 Lambda表达式遍历:");
    map.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));

    System.out.println();
    System.out.println("根据Key 寻找value="+map.get(1));

    System.out.println("remove(Object key) 根据key移除元素~");

    System.out.println();
    System.out.println("boolean containsKey(Object key): 是否包含指定的key"+map.containsKey(1));

    System.out.println();
    System.out.println("map.clear()   清空map,与map = null操作不同");
    System.out.println("map.isEmpty() 判断map是否为空");
}

Map.Entry的定义

Map的entrySet()方法返回一个实现Map.Entry接口的对象集合

Map.Entry中的常用方法

常见面试题:

集合源码解析

HashMap的底层实现原理?

在 JDK 1.7 中 HashMap 是以数组加链表的形式组成的

JDK 1.8 之后新增了红黑树的组成结构,当链表大于 8 并且容量大于 64 时,链表结构会转换成红黑树结构

HashMap 基于 Hash 算法实现的:

我们都知道HashMap 底层实现是: 数组+链表 JDK8: 数组+链表+红黑树

HashMap 和 Hashtable的异同?

相同:

不同:

HashMap中String、Integer这样的包装类适合作为K?

String、Integer等包装类的特性能够保证Hash值的不可更改性和计算准确性,能够有效的减少Hash碰撞的几率

泛型

JDK5.0新增

上一篇下一篇

猜你喜欢

热点阅读