Java 集合Collection(List、Set)Map

集合的理解和优点

  • 1)可以动态保存任意多个对象,使用比较方便!
  • 2)提供了一系列方便的操作对象的方法: add、remove、 set、 get等
  • 3)使用集合添加,删除新元素的示意代码-

Java集合的分类

Java的集合类很多,主要分为两大类,如图:

  • 1. 集合主要是两组(单列集合 , 双列集合)
  • 2. Collection 接口有两个重要的子接口 ListSet, 他们的实现子类都是单列集合
  • 3. Map 接口的实现子类 是双列集合,存放的 K-V
//Collection
//Map
ArrayList arrayList = new ArrayList();
arrayList.add("jack");
arrayList.add("tom");
HashMap hashMap = new HashMap();
hashMap.put("NO1", "北京");
hashMap.put("NO2", "上海");

Collection接口和常用方法

Java - Collection 接口及主要实现类_collections有什么实现-CSDN博客

 基本介绍

Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是 java.util.List 与 java.util.Set。其中:

  • List 的特点是有索引存取有序可重复
  • Set 的特点是无索引存取无序(LinkedHashSet除外)、不可重复

而两个子接口又分别有各自对应的实现类。
List 接口的主要实现类包括 java.util.ArrayList 和 java.util.LinkedList;
Set 接口的主要实现类有 java.util.HashSet、java.util.LinkedHashSet 和 java.util.TreeSet。

可用iterator迭代器

1、iterator

public class CollectionIterator{
@SuppressWarnings({"all"})public static void main(String[] args) {Collection col = new ArrayList();col.add(new Book("三国演义", "罗贯中", 10.1));col.add(new Book("小李飞刀", "古龙", 5.1));col.add(new Book("红楼梦", "曹雪芹", 34.6));//System.out.println("col=" + col);//现在希望能够遍历 col集合//1. 先得到 col 对应的 迭代器Iterator iterator = col.iterator();//2. 使用while 循环遍历//快捷键,快速生成 while=>itit//显示所有的快捷键的的快捷键 ctrl+jwhile (iterator.hasNext()) {Object obj = iterator.next();System.out.println("obj=" + obj);}//3. 当退出while 循环后 , 这时iterator迭代器,指向最后的元素// iterator.next();//NoSuchElementException//4. 如果希望再次遍历,需要重置我们的迭代器}
}

2、增强for循环

Collections工具类

Collections工具类介绍

  • 1) Collections是一个操作Set、List 和Map等集合的工具类
  • 2) Collections中提供了-系列静态的方法对集合元素进行排序、查询和修改等操作

排序操作:(均为static方法)

  • 1) reverse(List): 反转List中元素的顺序
  • 2) shuffle(List): 对List 集合元素进行随机排序
  • 3) sort(List): 根据元素的自然顺序对指定 List集合元素按升序排序
  • 4) sort(List, Comparator): 根据指定的Comparator产生的顺序对List集合元素进行排序
  • 5) swap(List, int, int): 将指定list集合中的 i处元素和 j处元素进行交换

应用案例演示Collections.java

import java.util.*;
public class Collections_ {public static void main(String[] args) {//创建ArrayList 集合,用于测试.List list = new ArrayList();list.add("tom");list.add("smith");list.add("king");list.add("milan");list.add("tom");//        reverse(List):反转 List 中元素的顺序Collections.reverse(list);System.out.println("list=" + list);
//        shuffle(List):对 List 集合元素进行随机排序
//        for (int i = 0; i < 5; i++) {
//            Collections.shuffle(list);
//            System.out.println("list=" + list);
//        }//        sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序Collections.sort(list);System.out.println("自然排序后");System.out.println("list=" + list);
//        sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序//我们希望按照 字符串的长度大小排序Collections.sort(list, new Comparator() {@Overridepublic int compare(Object o1, Object o2) {//可以加入校验代码.return ((String) o2).length() - ((String) o1).length();}});System.out.println("字符串长度大小排序=" + list);
//        swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换//比如Collections.swap(list, 0, 1);System.out.println("交换后的情况");System.out.println("list=" + list);//Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素System.out.println("自然顺序最大元素=" + Collections.max(list));//Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素//比如,我们要返回长度最大的元素Object maxObject = Collections.max(list, new Comparator() {@Overridepublic int compare(Object o1, Object o2) {return ((String)o1).length() - ((String)o2).length();}});System.out.println("长度最大的元素=" + maxObject);//Object min(Collection)//Object min(Collection,Comparator)//上面的两个方法,参考max即可//int frequency(Collection,Object):返回指定集合中指定元素的出现次数System.out.println("tom出现的次数=" + Collections.frequency(list, "tom"));//void copy(List dest,List src):将src中的内容复制到dest中ArrayList dest = new ArrayList();//为了完成一个完整拷贝,我们需要先给dest 赋值,大小和list.size()一样for(int i = 0; i < list.size(); i++) {dest.add("");}//拷贝Collections.copy(dest, list);System.out.println("dest=" + dest);//boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值//如果list中,有tom 就替换成 汤姆Collections.replaceAll(list, "tom", "汤姆");System.out.println("list替换后=" + list);}
}

查找、替换

  • 1) Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
  • 2) Object max(Collection, Comparator): 根据Comparator指定的顺序,返回给定集合中的最大元素
  • 3) Object min(Collection)
  • 4) Object min(Collection, Comparator)
  • 5) int frequency(Collection, object): 返回指定集合中指定元素的出现次数
  • 6) void copy(List dest,List src): 将src中的内容复制到dest中
  • 7) boolean replaceAll(List list, Object oldVal, Object newVal): 使用新值替换List对象的所有旧值

应用案例演示

List

ArrayList

  • ArrayList是线程不安全的,没有synchornized
  • 1) permits all elements, including null , ArrayList 可以加入nul,并且多个
  • 2) ArrayList是由数组来实现数据存储的
  • 3) ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码.在多线程情况下,不建议使用ArrayList
ArrayList底层结构和源码分析

1) ArrayList中维护了一个Object类型的数组elementData.
[debug看源码]transient Object[] elementData;
//transient表示瞬间,短暂的,表示该属性不会被序列号

2)当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1 .5倍。

3)如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。

ArrayList的基本使用
List list = new ArrayList();//add:添加单个元素
list.add("jack");
list.add(10);//list.add(new Integer(10))
list.add(true);
System.out.println("list=" + list);//remove:删除指定元素
list.remove(0);//删除第一个元素
list.remove(true);//指定删除某个元素
System.out.println("list=" + list);//contains:查找元素是否存在
System.out.println(list.contains("jack"));//T//size:获取元素个数
System.out.println(list.size());//2
// isEmpty:判断是否为空
System.out.println(list.isEmpty());//F
// clear:清空
list.clear();
System.out.println("list="+list);
// addAll:添加多个元素
ArrayListlist2=newArrayList();
list2.add("红楼梦");
list2.add("三国演义");
list.addAll(list2);
System.out.println("list="+list);// containsAll:查找多个元素是否都存在
System.out.println(list.containsAll(list2));//T// removeAll:删除多个元素
list.add("聊斋");
list.removeAll(list2);
System.out.println("list="+list);//[聊斋]

Vector

Vector 的基本介绍
  • 1) Vector类的定义说明
  • 2) Vector底层也是一 个对象数组,protected Object[] elementData;
  • 3) Vector 是线程同步的,即线程安全,Vector类的操作方法带有synchronized
    public synchronized E get(int index) {if (index > = elementCount)throw new ArrayIndexOutOfBoundsException(index); return elementData(index);
    }
  • 4)在开发中,需要线程同步安全时,考虑使用Vector
Vector和ArrayList的比较

LinkedList

LinkedList 的全面说明
  • 1) LinkedList底层实现了双向链表和双端队列特点
  • 2)可以添加任意元素(元素可以重复),包括null
  • 3)线程不安全,没有实现同步
LinkedList 的底层操作机制
  • 1) LinkedList底层维护了一个双向链表
  • 2) LinkedList中维护了两个属性first和last分别指向首节点和尾节点
  • 3)每个节点(Node对象) ,里面又维护了prev、next、 item三个属性,其中通过prev指向前一个, 通过next指向后一个节点。最终实现双向链表.
  • 4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。

ArrayList 和 LinkedList 的比较

如何选择ArrayList和LinkedList:

  • 1)如果我们改查的操作多选择ArrayList
  • 2) 如果我们增删的操作多 ,选择LinkedList
  • 3)一-般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList
  • 4)在个项目中, 根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList,也就是说,要根据业务来进行选择

Set 接口和常用方法

Set 接口基本介绍

无序(添加和取出的顺序不致),不允许重复元素,所以最多包含一个null

Set接口的常用方法

和List接口一样,Set接口也是Collection的子接口,因此,常用方法和Collection接口一样.

Set接口的遍历方式

同Collection的遍历方式一样,因为Set接口是Collection接口的子接口。

  • 1.可以使用迭代器
  • 2.增强for
  • 3.不能使用索引的方式来获取.
以 Set 接口的实现类 HashSet 来讲解Set 接口的方法
 public class SetMethod {public static void main(String[] args) {//1. 以 Set 接口的实现类 HashSet 来讲解Set 接口的方法//2. set 接口的实现类的对象(Set接口对象), 不能存放重复的元素, 可以添加一个null//3. set 接口对象存放数据是无序(即添加的顺序和取出的顺序不一致)//4. 注意:取出的顺序的顺序虽然不是添加的顺序,但是他的固定.Set set = new HashSet();set.add("john");set.add("lucy");set.add("john");//重复set.add("jack");set.add("hsp");set.add("mary");set.add(null);//set.add(null);//再次添加 nullfor(int i = 0; i <10;i ++) {System.out.println("set=" + set);}//遍历//方式1: 使用迭代器System.out.println("=====使用迭代器====");Iterator iterator = set.iterator();while (iterator.hasNext()) {Object obj = iterator.next();System.out.println("obj=" + obj);}set.remove(null);//方式2: 增强forSystem.out.println("=====增强 for====");for (Object o : set) {System.out.println("o=" + o);}//set 接口对象,不能通过索引来获取}
}

HashSet

HashSet 的全面说明
  • 1) HashSet实际上是HashMap,看下源码. 
  • 2)可以存放null值,但是只能有一一个null
  • 3) HashSet不保证元素是有序的,取决于hash后,再确定索引的结果。(即, 不保证存放元素的顺序和取出顺序一致)
  • 4) 不能有重复元素/对象. 在前面Set接口使用已经讲过
分析HashSet底层是HashMap, HashMap底层是(数组+链表+红黑树)
  • 1. HashSet底层是HashMap
  • 2.添加一个元素时,先得到hash值会转成->索引值
  • 3.找到存储数据表table ,看这个索引位置是否已经存放的有元素
  • 4.如果没有,直接加入
  • 5.如果有,调用equals比较,如果相同,就放弃添加,如果不相同,则添加到最后
  • 6.在Java8中,如果一条链表的元素个数到达TREEIFY THRESHOLD(默认是8),并且table的大小>=MIN TREEIFY CAPACITY(默认64), 就会进行树化(红黑树)

0521_韩顺平Java_HashSet源码解读1_哔哩哔哩_bilibili视频解释0521_韩顺平Java_HashSet源码解读1_哔哩哔哩_bilibili

LinkedHashSet
LinkedHashSet 的全面说明
  • 1) LinkedHashSet是HashSet的子类
  • 2) LinkedHashSet底层是一个LinkedHashMap,底层维护了一个数组+双向链表
  • 3) LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序(图),这使得元素看起来是以插入顺序保存的。
  • 4) LinkedHashSet不允许添重复元素

        1. LinkedHashSet 加入顺序和取出元素/数据的顺序一致
        2. LinkedHashSet 底层维护的是一个LinkedHashMap(是HashMap的子类)
        3. LinkedHashSet 底层结构 (数组table+双向链表)
        4. 添加第一次时,直接将 数组table 扩容到 16 ,存放的结点类型是 LinkedHashMap$Entry
        5. 数组是 HashMap$Node[] 存放的元素/数据是 LinkedHashMap$Entry类型

TreeSet

import java.util.Comparator;
import java.util.TreeSet;
public class TreeSet_ {public static void main(String[] args) {//1. 当我们使用无参构造器,创建TreeSet时,仍然是无序的//2. 老师希望添加的元素,按照字符串大小来排序//3. 使用TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)//   并指定排序规则//4. 简单看看源码///*1. 构造器把传入的比较器对象,赋给了 TreeSet的底层的 TreeMap的属性this.comparatorpublic TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}2. 在 调用 treeSet.add("tom"), 在底层会执行到if (cpr != null) {//cpr 就是我们的匿名内部类(对象)do {parent = t;//动态绑定到我们的匿名内部类(对象)comparecmp = cpr.compare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;else //如果相等,即返回0,这个Key就没有加入return t.setValue(value);} while (t != null);}*///        TreeSet treeSet = new TreeSet();TreeSet treeSet = new TreeSet(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {//下面 调用String的 compareTo方法进行字符串大小比较//如果要求加入的元素,按照长度大小排序//return ((String) o2).compareTo((String) o1);return ((String) o1).length() - ((String) o2).length();}});//添加数据.treeSet.add("jack");treeSet.add("tom");//3treeSet.add("sp");treeSet.add("a");treeSet.add("abc");//3System.out.println("treeSet=" + treeSet);}
}

Map 接口和常用方法

Map 接口实现类的特点(JDK8)

  • 1) Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value
  • 2) Map中的key和value 可以是任何引用类型的数据,会封装到HashMap$Node对象中
  • 3) Map中的key不允许重复,原因和HashSet 一样,分析过源码.
  • 4) Map中的value可以重复
  • 5) Map的key可以为null, value也可以为null,注意key为null,只能有一个,value为null ,可以多个.
  • 6)常用String类作为Map的key
  • 7) key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value

1.Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value(双列元素)
2.Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
3.Map中的key不允许重复,原因和HashSet一样,前面分析过源码.当有相同的k,相当于替换。
4.Map中的value可以重复
5.Map的key可以为null,value也可以为null,注意key为null,只能有一个,value 为null,可以多个
6. 常用String 类作为Map的 key
7. key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到对应的 value

Map接口常用方法

@SuppressWarnings({"all"})public class MapMethod{public static void main(String[] args){//演示map接口常用方法Map map = newHashMap();map.put("邓超",newBook("",100));//OKmap.put("邓超", "孙俪");//替换-> 一会分析源码map.put("王宝强", "马蓉");//OKmap.put("宋喆", "马蓉");//OKmap.put("刘令博", null);//OKmap.put(null, "刘亦菲");//OKmap.put("鹿晗", "关晓彤");//OKmap.put("hsp", "hsp 的老婆");System.out.println("map=" + map);// remove:根据键删除映射关系map.remove(null);System.out.println("map=" + map);//get:根据键获取值Object val = map.get("鹿晗");System.out.println("val=" + val);//size:获取元素个数System.out.println("k-v=" + map.size());//isEmpty:判断个数是否为0System.out.println(map.isEmpty());//F//clear:清除 k-v//map.clear();System.out.println("map=" + map);//containsKey:查找键是否存在System.out.println("结果=" + map.containsKey("hsp"));//T}
}

Map 接口遍历方法

  • 1.containsKey:查找键是否存在
  • 2.keySet:获取所有的键
  • 3.entrySet:获取所有关系k-v
  • 4.values:获取所有的值
public class MapFor {public static void main(String[] args) {Map map=newHashMap();map.put("邓超", "孙俪");map.put("王宝强", "马蓉");map.put("宋喆", "马蓉");map.put("刘令博", null);map.put(null, "刘亦菲");map.put("鹿晗", "关晓彤");//第一组: 先取出 所有的Key, 通过Key 取出对应的ValueSet keyset = map.keySet();//(1) 增强 forSystem.out.println("-----第一种方式-------");for (Object key : keyset) {System.out.println(key + "-" + map.get(key));}//(2) 迭代器System.out.println("----第二种方式--------");Iterator iterator = keyset.iterator();while (iterator.hasNext()) {Object key = iterator.next();System.out.println(key + "-" + map.get(key));}//第二组: 把所有的values取出Collection values = map.values();//这里可以使用所有的Collections使用的遍历方法//(1) 增强 forSystem.out.println("---取出所有的 value 增强 for----");for (Object value : values) {System.out.println(value);}//(2) 迭代器System.out.println("---取出所有的 value 迭代器----");Iterator iterator2 = values.iterator();while (iterator2.hasNext()) {Object value = iterator2.next();System.out.println(value);}//第三组: 通过EntrySet 来获取 k-vSet entrySet = map.entrySet();// EntrySet<Map.Entry<K,V>>//(1) 增强 forSystem.out.println("----使用 EntrySet 的 for 增强(第 3 种)----");for (Object entry : entrySet) {//将 entry 转成 Map.EntryMap.Entry m = (Map.Entry) entry;System.out.println(m.getKey() + "-" + m.getValue());}//(2) 迭代器System.out.println("----使用 EntrySet 的 迭代器(第 4 种)----");Iterator iterator3 = entrySet.iterator();while (iterator3.hasNext()) {Object entry = iterator3.next();//向下转型 Map.Entry//System.out.println(next.getClass());//HashMap$Node-实现-> Map.Entry (getKey,getValue)Map.Entry m = (Map.Entry) entry;System.out.println(m.getKey() + "-" + m.getValue());}}
}

HashMap

HashMap 小结

1) Map接口的常用实现类: HashMap、Hashtable和Properties。

2) HashMap是Map接口使用频率最高的实现类。

3) HashMap是以key-val对的方式来存储数据(HashMap$Node类型)[案例Entry]

4) key不能重复,但是值可以重复,允许使用nul键和null值。

5)如果添加相同的key,则会覆盖原来的key-val ,等同于修改.(key不会替换,val会替换)

6)与HashSet-样,不保证映射的顺序,因为底层是以hash表的方式来存储的. (jdk8的hashMap底层数组+链表+红黑树)

HashMap 底层机制及源码剖析

➢扩容机制[和HashSet相同]

  • 1) HashMap底层维护了Node类型的数组table,默认为null
  • 2)当创建对象时,将加载因子(loadfactor)初始化为0.75.
  • 3)当添加key-val时,通过key的哈希值得到在table的索引。然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,继续判断该元素的key和准备加入的key相是否等,如果相等,则直接替换val;如果不相等需要判断是树结构还是链表结构,做出相应处理。如果添加时发现容量不够,则需要扩容。
  • 4)第1次添加,则需要扩容table容量为16,临界值(threshold)为12 (16*0.75)
  • 5)以后再扩容,则需要扩容table容量为原来的2倍(32),临界值为原来的2倍,即24,依次类推。
  • 6)在Java8中,如果一条链表的元素个数超过TREEIFY THRESHOLD(默认是8 ),并且table的大小>= MIN TREEIFY CAPACITY(默认64),就会进行树化(红黑树)

0537_韩顺平Java_HMap源码解读_哔哩哔哩_bilibili

HashTable

HashTable的基本介绍

  • 1)存放的元素是键值对: 即K-V
  • 2) hashtable的键和值都不能为null,否则会抛出NullPointerException
  • 3) hashTable使用方法基本上和HashMap一样
  • 4) hashTable是线程安全的(synchronized), hashMap是线程不安全的
  • 5)简单看下底层结构
public class HashTableExercise {public static void main(String[] args) {Hashtable table = new Hashtable();//oktable.put("john", 100); //ok//table.put(null, 100); //异常 NullPointerException//table.put("john", null);//异常 NullPointerExceptiontable.put("lucy", 100);//oktable.put("lic", 100);//oktable.put("lic", 88);//替换table.put("hello1", 1);table.put("hello2", 1);table.put("hello3", 1);table.put("hello4", 1);table.put("hello5", 1);table.put("hello6", 1);System.out.println(table);//简单说明一下Hashtable的底层//1. 底层有数组 Hashtable$Entry[] 初始化大小为 11//2. 临界值 threshold 8 = 11 * 0.75//3. 扩容: 按照自己的扩容机制来进行即可.//4. 执行 方法 addEntry(hash, key, value, index); 添加K-V 封装到Entry//5. 当 if (count >= threshold) 满足时,就进行扩容//5. 按照 int newCapacity = (oldCapacity << 1) + 1; 的大小扩容.}
}

Hashtable 和 HashMap 对比

Map 接口实现类-Properties

Properties基本介绍
  • 1. Properties类继承自Hashtable类并且实现了 Map接口,也是使用一种键值对的形式来保存数据。
  • 2. 他的使用特点和Hashtable类似
  • 3. Properties 还可以用于从xxx.properties 文件中,加载数据到Properties类对象,并进行读取和修改
  • 4.说明:工作后xx.properties文件通常作为配置文件,这个知识点在IO流举例,有兴趣可先看文章
    旭东的博客 - 博客园 (cnblogs.com)
Properties基本使用
import java.util.Properties;
public class Properties_ {public static void main(String[] args) {//1. Properties 继承  Hashtable//2. 可以通过 k-v 存放数据,当然key 和 value 不能为 null//增加Properties properties = new Properties();//properties.put(null, "abc");//抛出 空指针异常//properties.put("abc", null); //抛出 空指针异常properties.put("john", 100);//k-vproperties.put("lucy", 100);properties.put("lic", 100);properties.put("lic", 88);//如果有相同的key , value被替换System.out.println("properties=" + properties);//通过k 获取对应值System.out.println(properties.get("lic"));//88//删除properties.remove("lic");System.out.println("properties=" + properties);//修改properties.put("john", "约翰");System.out.println("properties=" + properties);}
}

TreeMap

import java.util.Comparator;
import java.util.TreeMap;
public class TreeMap_ {public static void main(String[] args) {//使用默认的构造器,创建TreeMap, 是无序的(也没有排序)/*要求:按照传入的 k(String) 的大小进行排序*/
//        TreeMap treeMap = new TreeMap();TreeMap treeMap = new TreeMap(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {//按照传入的 k(String) 的大小进行排序//按照K(String) 的长度大小排序//return ((String) o2).compareTo((String) o1);return ((String) o2).length() - ((String) o1).length();}});treeMap.put("jack", "杰克");treeMap.put("tom", "汤姆");treeMap.put("kristina", "克瑞斯提诺");treeMap.put("smith", "斯密斯");treeMap.put("hsp", "韩顺平");//加入不了System.out.println("treemap=" + treeMap);/*解读源码:1. 构造器. 把传入的实现了 Comparator接口的匿名内部类(对象),传给给TreeMap的comparatorpublic TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}2. 调用put方法2.1 第一次添加, 把k-v 封装到 Entry对象,放入rootEntry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}2.2 以后添加Comparator<? super K> cpr = comparator;if (cpr != null) {do { //遍历所有的key , 给当前key找到适当位置parent = t;cmp = cpr.compare(key, t.key);//动态绑定到我们的匿名内部类的compareif (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;else  //如果遍历过程中,发现准备添加Key 和当前已有的Key 相等,就不添加return t.setValue(value);} while (t != null);}*/}
}

总结-开发中如何选择集合实现类

在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行选择,分析如下:

1)先判断存储的类型( 一组对象[单列]或一组键值对[双列])

2)一组对象[单列]: Collection接口
允许重复: List
        增删多: LinkedList [底层维护了一个双向链表]
        改查多: ArrayList [底层维护Object类型的可变数组]
不允许重复: Set
        无序: HashSet [底层是HashMap,维护了一个哈希表即(数组+链表+红黑树)]
        排序: TreeSet
        插入和取出顺序一致: LinkedHashSet ,维护数组+双向链表

3)、一组键值对[双列]: Map
        键无序: HashMap [底层是:哈希表jdk7: 数组+链表,jdk8: 数组+链表+红黑树]
        键排序: TreeMap 
        键插入和取出顺序一致: LinkedHashMap
        读取文件Properties

Java - Collection 接口及主要实现类_collections有什么实现-CSDN博客

java集合超详解_java集合使用-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/412721.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iPhone备忘录不小心删除了怎么办?

在日常使用iPhone的过程中&#xff0c;备忘录作为我们记录重要信息、灵感闪现和日常琐事的小帮手&#xff0c;其重要性不言而喻。然而&#xff0c;有时候因为操作失误或是不小心点击&#xff0c;我们可能会将珍贵的备忘录内容删除&#xff0c;这无疑会让人感到焦虑与不安。但请…

深入垃圾回收:理解GC的核心算法与实现

垃圾回收&#xff08;Garbage Collection&#xff0c;GC&#xff09;是现代编程语言中一项关键技术。它不仅解决了内存管理中的诸多问题&#xff0c;还为开发者提供了一个更高效、更安全的编程环境。本文将深入探讨GC的起源、主要算法以及这些算法在不同编程语言中的具体实现。…

考试:计算机网络(01)

网络功能和分类 计算机网络是计算机技术与通信技术相结合的产物&#xff0c;它实现了远程通信、远程信息处理和资源共享。 计算机网络的功能&#xff1a;数据通信、资源共享、管理集中化、实现分布式处理、负载均衡。 网络性能指标&#xff1a;速率、带宽(频带宽度或传送线路…

嵌入式数据库

概述 1.作用&#xff1a;存储大量数据&#xff0c;专业存储数据 存储在内存&#xff08;数组&#xff0c;变量&#xff0c;链表&#xff09;上的特点&#xff1a;程序运行结束&#xff0c;或者掉电&#xff0c;数据会丢失。 存储在硬盘&#xff08;文件&#xff09;上的特点…

vue3+ts+vite项目代码检查报错(vue-tsc)

报错原因&#xff1a;vue-tsc与typescrip版本不兼容 排查流程&#xff1a; 1、开始以为vue-tsc或者typescript版本太低&#xff0c;通过npm update更新&#xff0c;更新后还是报错 2、项目中package.json文件中typescript、vue-tsc版本并无兼容问题 3、控制台执行npm list发…

【HarmonyOS】模仿个人中心头像图片,调用系统相机拍照,从系统相册选择图片和圆形裁剪显示 (一)

【HarmonyOS】头像图片&#xff0c;调用系统相机拍照&#xff0c;从系统相册选择图片和圆形裁剪显示 &#xff08;一&#xff09; Demo效果展示&#xff1a; 方案思路&#xff1a; 使用photoAccessHelper实现系统相册选择图片的功能。此API可在无需用户授权的情况下&#xff…

万亿生成式AI市场,商汤迎来“长坡厚雪”

AI掀起了全球科技玩家的军备竞赛&#xff0c;然而声浪越强噪音越多&#xff0c;这个领域的混乱程度也变得远超以往。就连刚刚公布财报的英伟达&#xff0c;市场也没有买账&#xff0c;因为担心AI驱动的增长高峰已过&#xff0c;接下来&#xff0c;下游会更看重实际成果。 “囤…

javaee、ssm(maven)、springboot(maven)项目目录结构以及编译后文件目录存放路径

javaee项目目录结构&#xff1a; src下的文件或者是源码编译后都会放在WebRoot&#xff08;项目根目录&#xff09;文件夹\WebRoot\WEB-INF\classes目录中。 编译后的文件夹目录如下&#xff1a; 以上为普通的javaee项目目录结构&#xff0c;同maven工程目录结构是不一样的。…

07-图5 Saving James Bond - Hard Version(C)

哈哈&#xff0c;我是真的服了&#xff0c;写了好几天结果给我个这&#xff0c;气死我了&#xff0c;果然还有很大的进步空间。如果有c测试点4&#xff0c;就好了。 又写了一天&#xff0c;是真解决不了了&#xff0c;这个问题等我明白一定来解答 哈哈&#xff0c; 测试点提示内…

【SQL】餐馆营业额七日均线数据

目录 题目 分析 代码 题目 表: Customer ------------------------ | Column Name | Type | ------------------------ | customer_id | int | | name | varchar | | visited_on | date | | amount | int | -----------------------…

Docker 数据卷管理及优化

目录 1 数据卷实现的目的 2 为什么要用数据卷 3 docker的两种数据卷 3.1 bind mount 数据卷 实践实例&#xff1a; 3.2 docker managed 数据卷 实验实例&#xff1a; 3.3 bind mount 数据卷和docker managed 数据卷的对比 3.3.1 相同点&#xff1a; 3.3.2 不同点&#xff1a; …

【网络安全】服务基础第一阶段——第二节:Windows系统管理基础----虚拟化IP地址以及用户与组管理

目录 一、Windows网络测试工具 1.1.ping命令 1.2.tracert命令 二、IP实验内容 2.1 实验一 2.2 实验二 三、用户与组管理 3.1 用户与账户概述 3.2 用户管理 3.3 用户增删改查 3.4 增加用户 3.5 修改用户属性 3.6 删除用户 3.7 组账户概述 3.8 组账户增删改查 四、…

没有编程基础?这款数据分析工具也能轻松上手

在当前快节奏的工业环境中&#xff0c;工厂管理者越来越依赖数据分析来优化生产流程、提升效率、降低成本。然而&#xff0c;很多传统的数据分析工具不仅操作复杂&#xff0c;而且费用高昂&#xff0c;让不少工厂望而却步。最近&#xff0c;我发现了一款非常实用的报表工具&…

安卓主板_MTK安卓主板定制_联发科主板/开发板方案

这款安卓主板采用了联发科的MTK8788、MTK8768及MTK8766系列芯片平台&#xff0c;运用了64位四核/八核 Cortex-A53/A73架构&#xff0c;主频高达2.0 GHz。主板配置了4GB LPDDR3内存和64GB eMMC存储&#xff0c;同时配备了ARM Mail-T450 MP2图形处理单元(GPU)&#xff0c;使其在4…

Java性能优化传奇之旅--Java万亿级性能优化之电商平台高峰时段性能大作战:策略与趋势洞察

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

【Linux】共享内存

目录 原理 代码 在之前&#xff0c;无论是匿名管道还是命名管道&#xff0c;说到底都是基于文件的通信&#xff0c;也就意味着没有为了通信让OS单独设计一套通信模块代码&#xff0c;而是直接复用内核中文件相关的数据结构、缓冲区、代码来实现通信的&#xff0c;这在一定程度…

ET6框架(七)Excel配置工具

文章目录 一、Excel表的基本规则&#xff1a;二、特殊特殊标记三、编译路径说明四、动态获取数据五、可导表类型查看: 一、Excel表的基本规则&#xff1a; 在框架中我们的Excel配置表在ET > Excel文件夹中 1.在表结构中需要注意的是起始点必须在第三行第三列&#xff0c;且…

鸿蒙开发 数组改变,ui渲染没有刷新

问题描述&#xff1a; 数组push, 数组长度改变&#xff0c;ui也没有刷新 打印出了数组 console.log(this.toDoData.map(item > ${item.name}).join(, ), this.toDoData.length) 原代码&#xff1a; Text().fontSize(36).margin({ right: 40 }).onClick(() > {TextPicker…

mysql学习教程,从入门到精通,MySQL介绍(1)

1、MySQL 教程 本教程是为初学者准备的&#xff0c;以帮助他们理解与MySQL语言相关的基础知识和高级概念。 mysql MySQL 是最流行的关系型数据库管理系统&#xff0c;在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System&#xff1a;关系数据库管理系…

如何使用IDEA远程访问家里或者公司中无公网IP的内网MySQL数据库

文章目录 前言1. 本地连接测试2. Windows安装Cpolar3. 配置Mysql公网地址4. IDEA远程连接Mysql5. 固定连接公网地址6. 固定地址连接测试 前言 本教程主要介绍如何使用Cpolar内网穿透工具实现在IDEA中也可以远程访问家里或者公司的数据库&#xff0c;提高开发效率&#xff01;无…