13-集合框架

2023-10-31

引言

集合框架,理解为集合体系指的是由很多类共同构成,这些类之间存在关系(继承或实现),是成体系的类和接口。

一.认识集合

在java程序中 集合是存放数据的容器,它数组一样。但是但是 是存在差异的,从使用上说,集合更为方便,因为集合容量会随着元素的增减自动变化,而且集合提供丰富的方法来操作元素。而数组是一种非常基础的数据容器,直接使用不是很方便。

数组=它是语法层面提供的数据存储的简单容器,几乎所有的语言都提供了这个数组。
集合=数据结构+算法,不同的集合一般都依托于某种数据结构,比如ArrayList 底层使用的数组。LinkedList 底层使用链表

二.集合体系

image.png

三.List集合

3.1 认识List接口

List接口是Collection的一个子接口,它代表的是有序集合( 元素有序 有下标 可以重复 ),它在Collection基础上新增了一些个与下标操作相关的方法。

Collection和Collections(升序 降序 add )

3.2 List接口实现类

其主要的实现类有

  1. **ArrayList **
  2. LinkedList
  3. Vector

疑问?都是做相同的事情,为什么要搞个实现呢?
答案:因为他们底层的数据结构和算法乃至于线程安全性问题不同。

3.3 List接口常用方法

List方法来自两个部分,继承Collection的和自己的。

3.3.1 来自Collection的方法
boolean [**add**](../../java/util/Collection.html#add(E))([E](../../java/util/Collection.html) e)
确保此 collection 包含指定的元素(可选操作)。
boolean [**addAll**](../../java/util/Collection.html#addAll(java.util.Collection))([Collection](../../java/util/Collection.html)<? extends [E](../../java/util/Collection.html)> c)
将指定 collection 中的所有元素都添加到此 collection 中
void [**clear**](../../java/util/Collection.html#clear())()
移除此 collection 中的所有元素(可选操作)。
boolean [**contains**](../../java/util/Collection.html#contains(java.lang.Object))([Object](../../java/lang/Object.html) o)
如果此 collection 包含指定的元素,则返回 true。
boolean [**containsAll**](../../java/util/Collection.html#containsAll(java.util.Collection))([Collection](../../java/util/Collection.html)<?> c)
如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean [**equals**](../../java/util/Collection.html#equals(java.lang.Object))([Object](../../java/lang/Object.html) o)
比较此 collection 与指定对象是否相等。
int [**hashCode**](../../java/util/Collection.html#hashCode())()
返回此 collection 的哈希码值。
boolean [**isEmpty**](../../java/util/Collection.html#isEmpty())()
如果此 collection 不包含元素,则返回 true。
[Iterator](../../java/util/Iterator.html)<[E](../../java/util/Collection.html)> [**iterator**](../../java/util/Collection.html#iterator())()
返回在此 collection 的元素上进行迭代的迭代器。
boolean [**remove**](../../java/util/Collection.html#remove(java.lang.Object))([Object](../../java/lang/Object.html) o)
从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
boolean [**removeAll**](../../java/util/Collection.html#removeAll(java.util.Collection))([Collection](../../java/util/Collection.html)<?> c)
移除此 collection 中那些也包含在指定 collection 中的所有元素
boolean [**retainAll**](../../java/util/Collection.html#retainAll(java.util.Collection))([Collection](../../java/util/Collection.html)<?> c)
仅保留此 collection 中那些也包含在指定 collection 的元素
int [**size**](../../java/util/Collection.html#size())()
返回此 collection 中的元素数。
[Object](../../java/lang/Object.html)[] [**toArray**](../../java/util/Collection.html#toArray())()
返回包含此 collection 中所有元素的数组。
public static void main(String[] args) {

        //实例化集合
       Collection list  = new ArrayList();
        Actress a1 = new Actress("苍井空",30,'F',"上班的第一天.AVI");
        Actress a2 = new Actress("小泽玛利亚",31,'G',"坐轻轨去上班.AVI");
        Actress a3 = new Actress("波多野结衣",33,'C',"回家的诱惑.AVI");
        Actress a4 = new Actress("武藤兰",25,'D',"在学校的一天.AVI");

       //1 添加一个元素  add(Object obj):void
       list.add(a1);
       list.add(a2);
       list.add(a3);
       list.add(a4);

       //声明一个国产明星集合
       Collection other = new ArrayList();
       other.add( new Actress("白百何",40,'F',"失恋33天")  );
       other.add( new Actress("马蓉",41,'G',"宝强块回来")  );

       //2 添加一个集合 add(Collection obj):void
       list.addAll(other);

       //3 获得元素个数  size()
       System.out.println(list.size());

       //4 清空全部元素 clear():void
       //list.clear();
       //System.out.println(list.size());

       //5 判断是否包含指定元素
       System.out.println(list.contains(a4));
       System.out.println(list.containsAll(other));

       //6 判断集合是否为空集合 isEmpty():boolean
       System.out.println(list.isEmpty());

       //7 移除元素  remove(Object obj)   removeAll(Collection obj)
       //list.remove(a1);
       list.removeAll(other);

       //8 集合转数组  toArray()
       Object[] arr = list.toArray();
       System.out.println(Arrays.toString(arr));

       //9 集合求交集 retainAll(Collection list)
        Collection s1 = new ArrayList();
        s1.add("A");
        s1.add("B");
        s1.add("C");
        Collection s2 = new ArrayList();
        s2.add("A");
        s2.add("B");
        s2.add("f");
        s1.retainAll( s2);
        System.out.println(s1);

        //10 遍历
        for( Object o : list ){
            Actress actress = (Actress) o;
            System.out.println(actress.getName()+ actress.getSize());
        }
    }

3.3.2 自身扩展的方法
void [**add**](../../java/util/List.html#add(int, E))(int index, [E](../../java/util/List.html) element)
在列表的指定位置插入指定元素(可选操作)。
boolean [**addAll**](../../java/util/List.html#addAll(int, java.util.Collection))(int index, [Collection](../../java/util/Collection.html)<? extends [E](../../java/util/List.html)> c)
将指定 collection 中的所有元素都插入到列表中的指定位置
[E](../../java/util/List.html) [**get**](../../java/util/List.html#get(int))(int index)
返回列表中指定位置的元素。
int [**indexOf**](../../java/util/List.html#indexOf(java.lang.Object))([Object](../../java/lang/Object.html) o)
返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
int [**lastIndexOf**](../../java/util/List.html#lastIndexOf(java.lang.Object))([Object](../../java/lang/Object.html) o)
返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。
[E](../../java/util/List.html) [**remove**](../../java/util/List.html#remove(int))(int index)
移除列表中指定位置的元素(可选操作)。
[E](../../java/util/List.html) [**set**](../../java/util/List.html#set(int, E))(int index, [E](../../java/util/List.html) element)
用指定元素替换列表中指定位置的元素(可选操作)。
[List](../../java/util/List.html)<[E](../../java/util/List.html)> [**subList**](../../java/util/List.html#subList(int, int))(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
public static void main(String[] args) {
        List list = new ArrayList();
        list.add("唐僧");
        list.add("八戒");
        list.add("小明");
        list.add("晓东");

        //1 插入方法 add(int index , Object obj)
        list.add(1,"悟空");

        //2 获取元素的方法 get(int index):Object
        System.out.println(list.get(0));

        //3 移除元素 remove(int index):Object
        list.remove(2);

        //4  截取一段元素 subList( int index , int end )
        List sonList =   list.subList(1, 3);
        System.out.println(sonList);

        //5 修改指定位置的元素 set(int index , Object obj)
        list.set(0,"唐三藏");

        //6  查找元素下标 indexOf(Object obj)
        int n = list.indexOf("晓东");
        System.out.println(n);

        System.out.println("-------- 遍历 -----------");
        for( Object e : list){
            System.out.println(e);
        }
}

3.3.3 List集合遍历方式【掌握】
  1. 普通for循环
public static void main(String[] args) {
        Actress a1 = new Actress("苍井空",30,'F',"上班的第一天");
        Actress a2 = new Actress("小泽玛利亚",31,'G',"坐轻轨去上班");
        Actress a3 = new Actress("波多野结衣",33,'C',"回家的诱惑");
        Actress a4 = new Actress("武藤兰",25,'D',"在学校的一天");
        //实例化一个集合
        List list = new ArrayList();

        //核心中的核心方法 添加元素
        list.add(a4);
        list.add(a2);
        list.add(a1);
        list.add(a3);

        System.out.println("------------------- 有序集合遍历方式 1: 普通for --------------------");
        for( int i=0; i< list.size() ; i++   ){
            Object obj = list.get(i);//根据下下标找元素
            Actress actress = (Actress) obj;               
            System.out.println( actress.getProduct()  );
        }
}   
  1. 增强for循环
   public static void main(String[] args) {
        Actress a1 = new Actress("苍井空",30,'F',"上班的第一天");
        Actress a2 = new Actress("小泽玛利亚",31,'G',"坐轻轨去上班");
        Actress a3 = new Actress("波多野结衣",33,'C',"回家的诱惑");
        Actress a4 = new Actress("武藤兰",25,'D',"在学校的一天");
        //实例化一个集合
        List list = new ArrayList();

        //核心中的核心方法 添加元素
        list.add(a4);
        list.add(a2);
        list.add(a1);
        list.add(a3);
        System.out.println("-------------------  有序集合遍历方式 2: 增强for -------------------  ");
        for( Object obj : list ){
            Actress actress = (Actress) obj;
            System.out.println(actress.getName());
        }
   }       
  1. 迭代器遍历
public static void main(String[] args) {
        Actress a1 = new Actress("苍井空",30,'F',"上班的第一天");
        Actress a2 = new Actress("小泽玛利亚",31,'G',"坐轻轨去上班");
        Actress a3 = new Actress("波多野结衣",33,'C',"回家的诱惑");
        Actress a4 = new Actress("武藤兰",25,'D',"在学校的一天");
        //实例化一个集合
        List list = new ArrayList();

        //核心中的核心方法 添加元素
        list.add(a4);
        list.add(a2);
        list.add(a1);
        list.add(a3);
        System.out.println("-------------------  有序集合遍历方式 3: 迭代遍历 -------------------  ");
          // 迭代器
        Iterator it = list.iterator();
        while (  it.hasNext()  ){
            Object obj = it.next();
            Actress actress = (Actress) obj;
            System.out.println(actress.getName());
        }
    }

扩展 迭代器设计模式
image.png

3.4 List实现类区别【掌握】

3.4.1 ArrayList 特点

image.png
ArrayList 它底层依靠数组实现的 使用 Object[] elementData 存储数据。查询效率块 ,增删效率低。每次扩容增长0.5倍。ArrayList 是线程不安的,多线程环境下不保证数据一致性。

3.4.2 Vector 特点

image.png
它和ArrayList实现原理一样。默认每次扩容增长1倍,这个类是一个古老的集合类,JDK1.O提供的有序集合类,他是线程安全的,效率低,在JDK1.2推出的ArrayList 代替它的功能,这个类几乎不用了。

3.4.3 LinkedList 特点

LinkedList 底层使用链表数据结构实现,链表结构理解如下:
image.png

private static class Node { // 它是一个内部类
E item; //数据区
Node next; //前元素地址
Node prev; //后元素地址

Node(Node<E> prev, E element, Node<E> next) {
    this.item = element;
    this.next = next;
    this.prev = prev;
}

}

该类的继承和实现关系如下:
image.png
链表这种数据结构,查询效率低,增删效率高,当然他还是实现了队列相关功能,同时它也不保证线程安全。

四.泛型

4.1 泛型概念

泛型指的是类型参数化的一个技术,在设计类/接口的时候,如果他们内部某些地方的类型无法确定,可以使用一个占位符,先站位,使用这个类或接口的时候再指定(把类型的确定推迟到这个类具体使用的时候)。

4.2 泛型集合使用

//泛型集合 使用
public class GenericCollectionDemo {
    public static void main(String[] args) {
        Actress a1 = new Actress("苍井空",30,'F',"上班的第一天");
        Actress a2 = new Actress("小泽玛利亚",31,'G',"坐轻轨去上班");
        Actress a3 = new Actress("波多野结衣",33,'C',"回家的诱惑");
        Actress a4 = new Actress("武藤兰",25,'D',"在学校的一天");

        //实例化集合指定泛型参数
        List<Actress> list = new ArrayList<>();
        //添加对象
        list.add(a1);
        list.add(a2);
        list.add(a3);
        list.add(a4);

        //遍历
        for( Actress o : list){ //不用Object 用泛型指定的类型就可以了,不用转型方便
            System.out.println(o.getName());
        }
    }
}

开发中通常都是使用泛型集合,保证元素的单一性,同时元素类型不会提升,使用时无需转型,顶呱呱。

4.3 泛型类/接口定义/泛型方法

比如定义一个位置类,但是不想把x y 坐标的类型定死,这是使用X,Y字母 来占位,通常使用的有E K V T 这些。

//位置
public class Position<X,Y> {
    X x;
    Y y;
    public Position(X x, Y y) {
        this.x = x;
        this.y = y;
    }
    public X getX() {
        return x;
    }
    public void setX(X x) {
        this.x = x;
    }
    public Y getY() {
        return y;
    }
    public void setY(Y y) {
        this.y = y;
    }
}
//泛型原理
public class GenericPrinciple {
    public static void main(String[] args) {
        //使用类时 必须指定具体X Y字母的类型
        Position<Integer,Integer> position = new Position<>(10,20);
        System.out.println(position.getX());
        System.out.println(position.getY());
        System.out.println("----------------------------");
        //使用类时 必须指定具体X Y字母的类型
        Position<String,String> position2 = new Position<>("东经30","北纬50");
        System.out.println(position2.getX());
        System.out.println(position2.getY());
    }
}

使用泛型技术可以让代码更灵活,一个类当无数个类使用,需要注意的是 基本数据类型不支持泛型,需要使用其包装类

4.4 泛型限定

指的是设计泛型方法的时候,方法参数存在的一些泛型类型要求

public static void m1(List<Integer> obj ){  // 接收一个特定泛型的集合 参数

}

public static void m2( List<?> obj   ){ // 接收一个任意泛型的集合 参数 ?不限定

}
public static void m3(List< ? super Integer > obj ){ // 接收一个特定泛型及其父类类型 的集合参数

}
public static void m4(List< ?extends Number > obj ){ // 接收一个特定泛型及其子类类型 的集合参数

}

4.5 泛型擦除

java中泛型是一种伪泛型,编译效果,一旦编译泛型就没有泛型信息了,所以需要注意就是不同的泛型类型不可重载。

public static void m1(List<Integer> obj ){

}
public static void m1(List<Double> obj ){ // 报错不可重载

} 
//--------------------泛型擦除后------------------------
public static void m1(List obj ){ // 参数一样了

}
public static void m1(List obj ){ // 参数一样了

}

4.6 泛型不支持多态

public static void main(String[] args) {
    List<Integer> brr = new ArrayList<>();

    List<Number> arr ;

    arr= brr; //报错 不可直接赋值,不考虑多态问题,泛型类+   具体类型完全是一个全新类型。
}

课堂案例
image.png

按图变写歌曲类
创建若干对象存入集合(使用泛型集合)
使用3种遍历方式输出每个对象信息。

五.Set集合

5.1 Set接口的特点

Set表示的是 无序 无下标 元素不可重复 ,它也是一个子接口但是没有扩展新的方法,也就是说只有Collection接口中的方法。

5.2 Set接口的实现类

  1. ** HashSet**
  2. ** LinkedHashSet**
  3. ** TreeSet**

5.3 常用API

和Collection中的一致,无需重复学习。

5.4 无序集合遍历

  1. 迭代器
  2. 增强for
public class SetDemo {

    public static void main(String[] args) {

        //无序无下标不可重复
        Set<String> sets = new HashSet<>();
        sets.add("Java");
        sets.add("MySQL");
        sets.add("Java");
        sets.add("H5");
        sets.add("MMP");
        sets.add("HMP");
        System.out.println(sets); //[Java, MySQL, php, H5]


        //遍历
        System.out.println("---------------迭代器-----------------");
        Iterator<String> it = sets.iterator();
        while ( it.hasNext() ){
            String obj = it.next();
            System.out.println(obj);
        }
        System.out.println("---------------增强for-----------------");
        for( String obj : sets){
            System.out.println(obj);
        }
        System.out.println("---------------查找-----------------");
        for( String obj : sets){
            char c = obj.charAt(0);
            if(c=='H'){
                System.out.println(obj);
            }
        }
    }
}

Set集合不可以单独直接取出某个元素,需要遍历筛选出你要的元素

5.5 HashSet去重

HashSet去重原理:
添加元素的时候,先判断对象的hashcode 是否与现有元素的hashcode 相同。
* 不相同:直接保存
* 相同: 需要进一步判断 equals 是否和现有元素相同
* 相同: 放弃保存
* 不同: 保存

_重写两个方法 hashCode() equals() _

class Book{

    String name;
    String author;

    public Book() {
    }

    public Book(String name, String author) {
        this.name = name;
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                '}';
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (author != null ? author.hashCode() : 0);
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Book book = (Book) o;

        if (name != null ? !name.equals(book.name) : book.name != null) return false;
        return author != null ? author.equals(book.author) : book.author == null;
    }
}

HashSet 集合底层 是套用 HashMap

5.6LinkedHashSet 【了解】

HashSet子类,可以记录元素的添加顺序,底层使用LinkedHashMap。
image.png

public class LinkedHashSetDemo {

    public static void main(String[] args) {

        Set<String> sets = new LinkedHashSet<>();
        sets.add("Hello");
        sets.add("CSS");
        sets.add("MySQL");
        sets.add("Hello");

        System.out.println(sets);
    }
}

5.7TreeSet 【了解】

他是Sorted接口的实现类,具备元素可排序的能力,可以把元素按照从小到大或者从大到小排列(可以把元素升序降序排列)。它的底层套娃 TreeMap
image.png

5.7.1 自然排序

自然排序需要 让类实现Comparable 接口,这是一个排序接口 ,需要重写一个方法 public int compareTo(T o);
这个方法用于让用户 自定义比较规则。

Book类

package set;

public class Book implements   Comparable  {
    String name;
    String author;
    double pirce;
    //省略其他
    //自动定义比较规则的方法
    @Override
    public int compareTo(Object o) {
        Book book = (Book) o;
        if(this.pirce > book.pirce){
            return 1;
        }
        if( this.pirce< book.pirce ){
            return -1;
        }
        //return 0; //去重
        return  this.name.compareTo(book.name);
    }
}

测试类

public class TreeSetDemo {
    public static void main(String[] args) {
        System.out.println("------------自用自然排序------------------");
        Set<Book> books = new TreeSet<>();
        books.add( new Book("西游记","a",10) );
        books.add( new Book("西游记后传","a",23) );
        books.add( new Book("西游记前传","a",9) );
        for (Book book : books) {
            System.out.println(book);
        }
    }
}

5.7.2 排序器排序

这种方式需要在创建TreeSet实例的时候传入一个Comparator接口的实例,通常使用匿名内部类来做。元素类不需要实现Comparable 接口。

package set;

public class Book  {
    String name;
    String author;
    double pirce;
    //省略其他
}
public class TreeSetDemo {

    public static void main(String[] args) {
     
        System.out.println("-----------使用排序器排序-------------------");
        Set<Book> books = new TreeSet<>( new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                if(o1.pirce>o2.pirce){
                    return 1;
                }
                if(o1.pirce<o2.pirce){
                    return -1;
                }
                return 0;
            }
        } );
        books.add( new Book("西游记","a",10) );
        books.add( new Book("西游记后传","a",23) );
        books.add( new Book("西游记前传","a",9) );
        for (Book book : books) {
            System.out.println(book);
        }
    }
}

六.Map集合

6.1 理解Map 映射

映射描述的是key到value对应关系,也就是所,map对象保存的是一组对应关系。

6.1.1 Map映射体系

image.png

6.1.2 map的空间结构

image.png

6.2 常用API

void [**clear**](../../java/util/Map.html#clear())()
从此映射中移除所有映射关系(可选操作)。
boolean [**containsKey**](../../java/util/Map.html#containsKey(java.lang.Object))([Object](../../java/lang/Object.html) key)
如果此映射包含指定键的映射关系,则返回 true。
boolean [**containsValue**](../../java/util/Map.html#containsValue(java.lang.Object))([Object](../../java/lang/Object.html) value)
如果此映射将一个或多个键映射到指定值,则返回 true。
[Set](../../java/util/Set.html)<[Map.Entry](../../java/util/Map.Entry.html)<[K](../../java/util/Map.html),[V](../../java/util/Map.html)>> [**entrySet**](../../java/util/Map.html#entrySet())()
返回此映射中包含的映射关系的 [Set](../../java/util/Set.html)
视图。
boolean [**equals**](../../java/util/Map.html#equals(java.lang.Object))([Object](../../java/lang/Object.html) o)
比较指定的对象与此映射是否相等。
[V](../../java/util/Map.html) [**get**](../../java/util/Map.html#get(java.lang.Object))([Object](../../java/lang/Object.html) key)
返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
int [**hashCode**](../../java/util/Map.html#hashCode())()
返回此映射的哈希码值。
boolean [**isEmpty**](../../java/util/Map.html#isEmpty())()
如果此映射未包含键-值映射关系,则返回 true。
[Set](../../java/util/Set.html)<[K](../../java/util/Map.html)> [**keySet**](../../java/util/Map.html#keySet())()
返回此映射中包含的键的 [Set](../../java/util/Set.html)
视图。
[V](../../java/util/Map.html) [**put**](../../java/util/Map.html#put(K, V))([K](../../java/util/Map.html) key, [V](../../java/util/Map.html) value)
将指定的值与此映射中的指定键关联(可选操作)。
void [**putAll**](../../java/util/Map.html#putAll(java.util.Map))([Map](../../java/util/Map.html)<? extends [K](../../java/util/Map.html),? extends [V](../../java/util/Map.html)> m)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
[V](../../java/util/Map.html) [**remove**](../../java/util/Map.html#remove(java.lang.Object))([Object](../../java/lang/Object.html) key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
int [**size**](../../java/util/Map.html#size())()
返回此映射中的键-值映射关系数。
[Collection](../../java/util/Collection.html)<[V](../../java/util/Map.html)> [**values**](../../java/util/Map.html#values())()
返回此映射中包含的值的 [Collection](../../java/util/Collection.html)
视图。
public class TestMap {

    public static void main(String[] args) {
        //实例化一个map集合
        Map<String,String> maps= new HashMap<>();
        //1 添加元素(key-value) put(K key, V value)
        maps.put("apple","苹果");
        maps.put("actress","女优");
        maps.put("student","学生");
        maps.put("teacher","老师");
        //2 根据key 获得value    get(K key):V
        String actress = maps.get("apple");
        System.out.println(actress);
        //3 获得元素个数          size():int
        System.out.println(maps.size());
        //4 清空全部元素          clear():void
         //maps.clear();
        //5 检查键 containsKey(K key):boolean
        System.out.println(maps.containsKey("apple1"));
        //6 检查值 containsValue(K key):boolean
        System.out.println(maps.containsValue("女优"));

        //7 移除元素 remove(K key):V
        maps.remove("teacher");
        System.out.println(maps);
    }
}

6.3 Map集合遍历[ 掌握 ]

6.3.1 根据keySet()

Map集合提供了一种视图,这个视图就是可以看见和搜集全部键的集合

/**
 * Map集合遍历
 */
public class MapEach {

    public static void main(String[] args) {

        //实例化Map集合
        Map<String,Book> books = new HashMap<>();

        //添加元素
        books.put( "b1" , new Book("《Java从入门到放弃》","刘备",99.8) );
        books.put( "b2" , new Book("《MySQL从删库到跑路》","关羽",19.8) );
        books.put( "b3" , new Book("《JavaScript从入门到放弃》","刘备",20.8) );

        System.out.println("---------------------- keySet()----------------------");
        Set<String> keys = books.keySet();
        for( String key : keys ){
            System.out.println(key +"-"+ books.get(key).name ) ;
        }
    }

}

6.3.1 根据entrySet()

Map集合提供了一种视图,这个视图就是可以看见和搜集全部的 把键值视为一个整体(Map.Entry<K,V>) 的集合。Entry是Map中的内部类类型。

/**
 * Map集合遍历
 */
public class MapEach {

    public static void main(String[] args) {
        //实例化Map集合
        Map<String,Book> books = new HashMap<>();
        //添加元素
        books.put( "b1" , new Book("《Java从入门到放弃》","刘备",99.8) );
        books.put( "b2" , new Book("《MySQL从删库到跑路》","关羽",19.8) );
        books.put( "b3" , new Book("《JavaScript从入门到放弃》","刘备",20.8) );

        System.out.println("-----------------------entrySet()---------------------");
        Set< Map.Entry<String, Book> > entrySet = books.entrySet();
        for( Map.Entry<String, Book> entry : entrySet ){
            System.out.println( entry.getKey() + "-"+ entry.getValue().name );
        }
    }
}

6.3.2 遍历全部值values()

Map集合提供了一种视图,这个视图就是可以看见和搜集全部的value,全部的value构成一个Collection的集合,而搜集的方法就是 values():Collection。

public class MapEach {

    public static void main(String[] args) {
        //实例化Map集合
        Map<String,Book> books = new HashMap<>();
        //添加元素
        books.put( "b1" , new Book("《Java从入门到放弃》","刘备",99.8) );
        books.put( "b2" , new Book("《MySQL从删库到跑路》","关羽",19.8) );
        books.put( "b3" , new Book("《JavaScript从入门到放弃》","刘备",20.8) );

        System.out.println("-----------------------values()------------------------");
        Collection<Book> values = books.values();
        for ( Book book  :values){
            System.out.println(book.name);
        }
    }

}

6.4 Map 集合实现类区别

1. HashMap 特点

它是最常用的Map实现类,底层使用 hash表,它是一种(数组+链表+红黑数)数据结构,不保证线程安全。HashSet底层就是使用的HashMap实现的功能,并且只使用了它的Key空间。HashMap的键是无序的,且允许包含空键和空值。
image.png

2. Hashtable 特点

它也是Map实现类,但是它是一个古老映射集合,是jdk1.0的集合,它是线程安全的。实现原理也就是hash表,就是说实现原理和HashMap一样,API兼容。 它不允许出现空键和空值 ,HashMap可以。可以说HashMap的出现就是为了替代Hashtable,Hashtable 几乎不用。

3. Properties 特点

它是Hashtable子类,可以实现从 properties文件中加载数据。开发中很常用。

properties-》xml-》mysql-》yaml 鸭儿文件

4. TreeMap 特点

它是一个底层通过红黑树实现,可以把key进行排序。TreeSet就是可以把元素排序,应为它的底层就是使用的TreeMap,并就是利用key空间来装元素。
TreeMap 虽然可以对key排序,但是对Key的类型有要求,要求Key类型实现Comparable 接口。 这就是为什么使用TreeSet时元素类型需要实现接口的原因。

arraylist linkedlist hashmap hashset

Collection 提供所有集合常用操作方法 ,这是一个接口:list set

Collections 提供所有集合的常用算法方法,这是一个类

作业:
请用 arraylist 和linkedLIst + 递归 编写 菜单目录 无限树遍历

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

13-集合框架 的相关文章

  • Java - 为什么不允许 Enum 作为注释成员?

    It says 原始 String Class an Enum 另一个注释 上述任何一个的数组 只有这些类型才是合法的 Annotation 成员 为什么泛型 Enum 不能成为 Annotation 的成员 例如 Retention Re
  • Eclipse 在源代码管理中保存操作

    我们希望找到一种在签入之前执行代码标准的 轻量级 方法 我们真的很喜欢使用 Eclipse 内置的想法保存操作 go to Preferences gt gt Java gt gt Editor gt gt Save Actions 其中有
  • 如何使用 Java 中的 Web 服务(例如 Axis2)发送复杂对象的数组或集合?

    我对 SOAP Web 服务还比较陌生 虽然我完成了一些较小的 Web 服务项目 但我偶然从来不需要返回 或用作参数 复杂 对象的数组或集合 当我尝试这样做时 根据我的 SOAP 绑定风格 我会得到不同的奇怪行为 当我使用RPC 文字 我可
  • 在文本文件中写入多行(java)

    下面的代码是运行命令cmd并使用命令行的输出生成一个文本文件 下面的代码在 Eclipse 的输出窗口中显示了正确的信息 但在文本文件中只打印了最后一行 谁能帮我这个 import java io public class TextFile
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • 如何使用 Java 处理 Selenium WebDriver 中的新窗口?

    这是我的代码 driver findElement By id ImageButton5 click Thread sleep 3000 String winHandleBefore driver getWindowHandle drive
  • 按第一列排序二维数组,然后按第二列排序

    int arrs 1 100 11 22 1 11 2 12 Arrays sort arrs a b gt a 0 b 0 上面的数组已排序为 1 100 1 11 2 12 11 22 我希望它们按以下方式排序a 0 b 0 首先 如果
  • Java 文件上传速度非常慢

    我构建了一个小型服务 它从 Android 设备接收图像并将其保存到 Amazon S3 存储桶中 代码非常简单 但是速度非常慢 事情是这样的 public synchronized static Response postCommentP
  • Hazelcast 分布式锁与 iMap

    我们目前使用 Hazelcast 3 1 5 我有一个简单的分布式锁定机制 应该可以跨多个 JVM 节点提供线程安全性 代码非常简单 private static HazelcastInstance hInst getHazelcastIn
  • 以编程方式在java的resources/source文件夹中创建文件?

    我有两个资源文件夹 src 这是我的 java 文件 资源 这是我的资源文件 图像 properties 组织在文件夹 包 中 有没有办法以编程方式在该资源文件夹中添加另一个 properties 文件 我尝试过这样的事情 public s
  • react-native run-android 失败并出现错误:任务 ':app:dexDebug' 执行失败

    我使用的是 Windows 8 1 和react native cli 1 0 0 and react native 0 31 0 添加后react native maps对于该项目 我运行了命令react native upgrade并给
  • Struts 2 + Sitemesh 3 集成 - FreemarkerDecoratorServlet 中的 NPE

    我将 Struts 2 版本 2 3 14 3 与 Sitemesh 3 版本 3 0 alpha 2 一起使用 并且在某些情况下遇到 NullPointerException 首先 这是我的 web xml 中的 struts2 site
  • 在 Spring 中重构这个的最佳方法?

    private final ExecutorService executorParsers Executors newFixedThreadPool 10 public void parse List
  • 如何在JSTL中调​​用java方法? [复制]

    这个问题在这里已经有答案了 这可能是重复的问题 我只想调用不是 getter 或 setter 方法的方法例如 xyz 类的 makeCall someObj stringvalue Java类 Class XYZ public Strin
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 具有特定参数的 Spring AOP 切入点

    我需要创建一个我觉得很难描述的方面 所以让我指出一下想法 com x y 包 或任何子包 中的任何方法 一个方法参数是接口 javax portlet PortletRequest 的实现 该方法中可能有更多参数 它们可以是任何顺序 我需要
  • Trie 数据结构 - Java [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 是否有任何库或文档 链接提供了在 java 中实现 Trie 数据结构的更多信息 任何帮助都会很棒 Thanks 你可以阅读Java特里树
  • GUI Java 程序 - 绘图程序

    我一直试图找出我的代码有什么问题 这个想法是创建一个小的 Paint 程序并具有红色 绿色 蓝色和透明按钮 我拥有我能想到的让它工作的一切 但无法弄清楚代码有什么问题 该程序打开 然后立即关闭 import java awt import
  • 如何修复:“无法解析类型 java.lang.CharSequence。它是从所需的 .class 文件间接引用的”消息? [复制]

    这个问题在这里已经有答案了 我正在尝试使用这个字符串 amountStr amountStr replace replace replace 但我收到一条错误消息 我知道我收到的错误消息是因为我刚刚发布的字符串已过时 所以我想知道该字符串的

随机推荐

  • html5图片并列排版,小编,图片与文字并排怎么排版呢?

    图文排版 H5秀 手机图文 小伙伴 小米 我想左边放图片 右边是文字 但是图片插入之后 再编辑文字只能在下一行 我就直接调整段前距 但有时候预览它会错位 想问图片与文字并排如何排版出来呢 这是一个日经题 设置段前距或许是一个方法 但设定的数
  • Windows下PyTorch1.5的下载安装

    在安装PyTorch之前要先安装好CUDA cudNN 以及anaconda 还有就是编译器pycharm 然后你才能开始安装PyTorch 目录 1 创建虚拟环境 2 去PyTorch官网 3 发现警告 4 解决办法 5 pip list
  • 解析波士顿动力Handle机器人背后的技术(附PPT+视频)

    转 http www leiphone com news 201703 URrR8CG2tmtghNDl html 导语 Boston Dynamics 在机器人动力方面堪称翘楚 其由双足或多足机器人组成的机器人天团总是时不时能给我们带来惊
  • Python3 pip

    Python3 pip pip 是 Python 包管理工具 该工具提供了对 Python 包的查找 下载 安装 卸载的功能 软件包也可以在 https pypi org 中找到 目前最新的 Python 版本已经预装了 pip 注意 Py
  • Nginx添加SSL模块

    目录 一 SSL 概述 SSL证书 HTTPS SSL工作原理 二 创建SSL证书 安装openssl 生成证书 三 nginx配置 nginx打补丁添加模块 nginx conf配置 四 访问 一 SSL 概述 SSL Security
  • 向日葵权限mac

    问题 权限打开后自动关上 解决 mac上几乎所有远程软件都会出现这种权限设置问题 换了腾讯会议或其他也没用 方法一 试试先打开系统的安全性设置 将向日葵软件从隐私框里移出来 点击 号移除 再重新添加进去 方法二 将权限的勾选去掉 再添加 然
  • EFCore 数据模型 和 值转换

    操作中经常要涉及到模型和值转换的问题 这里记录一下 实际使用过程中遇到过的问题 而非功能的全部 模型 EFCore中支持字段 参考地址 https docs microsoft com zh cn ef core modeling back
  • SpringBoot框架详解,实战入门教程

    SpringBoot作为当下Java开发最常用的技术框架 相信你也一定听过很多次了 那么到底什么是SpringBoot SpringBoot又有什么用呢 跟着动力节点的视频快速入门springboot 视频观看资源 https www bi
  • CIKM 2023|TASTE:通过文本匹配缓解序列化推荐中流行偏差问题

    序列化推荐系统旨在根据用户的浏览历史动态地为用户推荐下一个商品 这在Yelp TikTok Amazon等众多Web应用程序中发挥着至关重要的作用 这些推荐系统通过使用不同的神经网络架构来学习用户 商品交互中商品之间的依赖关系 从而对用户行
  • Qt:文管打开方式:选择并设置默认程序

    默认启动APP配置文件 local share applications mimeapps list config mimeapps list etc gnome defaults list 全局 QAction action choose
  • 整理一些spring常见的扩展点

    一 各种后处理器 1 1 BeanDefinition与BeanFactory扩展 1 1 1 BeanDefinitionRegistryPostProcessor接口 Extension to the standard link Bea
  • 解决Vue前端报错——Error: Cannot find module ‘node-sass‘

    解决Vue前端报错 Error Cannot find module node sass 今天在使用VsCode 导入一个新Vue項目文件夹的时候出现了以下的问题 npm run dev提示 Cannot find module node
  • Winform自定义表单(转)

    出处 http www newlifex com showtopic 167 aspx 好吧 附件真的损坏了 原始代码我也没有了 再提取我也没精力了 不好意思 哪位之前下过可以重发一遍吗 不过即使没有也可以参考下面几个示例很快就可以做出来了
  • docker容器二之Dockerfile详解+镜像的优化

    文章目录 Dockerfile详解 Dockerfile常用指令 Dockerfile示例 实验截图 解决报错 Shell和exec格式的区别 镜像的优化 Dockerfile详解 Dockerfile常用指令 首先先明白 什么是Docke
  • matlab/simulink scope 示波器添加菜单栏的方法

    在用matlab simulink scope 示波器的时候 弹出的图像框没有菜单栏 保存复制等操作极为不便 以下操作可以让示波器的图形窗口显示出菜单栏 在matlab的command window里执行下面两句代码 set 0 ShowH
  • 【华为OD机试】工号不够用了怎么办【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 3020年 空间通信集团的员工人数突破20亿人 即将遇到现有工号不够用的窘境 现在 请你负责调研新工号系统 继承历史传统 新的工号系统由小写英文字母 a z 和数字
  • spring的ApplicationContext 得到方式

    ClassPathXmlApplicationContext会自己在CLASSes里面找 不过我只是把配置文件放在src文件下成功找到过 String paths applicationContextDataSource xml appli
  • MarkDown中写流程图的方法

    序 Mermaid FlowChat 中译为美人鱼 就好比一条美人鱼在流动构成了流程图 是一种在MarkDown中以特定格式的文字生成流程图或是图标的方法 一种简单的降价式脚本语言 用于通过javascript从文本生成图表 官方文档点这里
  • 【华为OD机试真题】94、猜密码

    文章目录 一 题目 题目描述 输入输出 样例1 二 代码与思路参考 C语言思路 C代码 C 语言思路 C 代码 Java语言思路 Java代码 Python语言思路 Python代码
  • 13-集合框架

    引言 集合框架 理解为集合体系指的是由很多类共同构成 这些类之间存在关系 继承或实现 是成体系的类和接口 一 认识集合 在java程序中 集合是存放数据的容器 它数组一样 但是但是 是存在差异的 从使用上说 集合更为方便 因为集合容量会随着