Java基础-集合
一、集合概述
(本文参考博客:https://www.cnblogs.com/chenglc/p/8073049.html)
集合可以看作一个容器,集合中的对象可以很容易存放到集合中,也很容易将其从集合中取出来,还可以按一定的顺序摆放。Java中提供了不同的集合类,这些类具有不同的存储对象的方式,并提供了相应的方法方便用户对集合进行遍历。
数组与集合:数组不是面向对象的,存在明显的缺陷,集合弥补了数组的缺点,比数组更灵活更实用,而且不同的集合框架类可适用不同场合。
- 数组能存放基本数据类型和对象,而集合类存放的都是对象,集合类不能存放基本数据类型。数组和集合存放的对象皆为对象的引用地址。
- 数组容易固定无法动态改变,集合类容量动态改变。
- 数组无法判断其中实际存有多少元素,length只告诉了数组的容量,而集合的size()可以确切知道元素的个数。
- 集合有多种实现方式和不同适用场合,不像数组仅采用顺序表方式。
- 集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性即可实现各种复杂操作,大大提高了软件的开发效率。
Collection和Map,是集合框架的根接口:
二、Collection接口
Collection的子接口:
Set:接口:实现类- HashSet、LinkedHashSet
Set的子接口SortedSet接口:实现类-TreeSet
List:接口:实现类- LinkedList,Vector,ArrayList
Collection 具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、TreeSet等。
Collection集合常用方法即可以操作Set集合,也可以操作Queue和List集合:
代码演示:
public void testCollection() { // 创建Collection接口的实现 Collection collection = new ArrayList<>(); // 添加元素 collection.add("嘻嘻"); String src = "????"; collection.add(src); System.out.println(collection); // 创建Collection的实现 Collection<String> coll = new HashSet<>(); coll.add("?"); coll.add("?"); coll.add("?"); System.out.println(coll); // 添加一个集合数据 collection.addAll(coll); // 输出集合的长度 System.out.println(collection); // 判断是否包含 System.out.println(collection.contains("?")); // 移除元素 collection.remove("?"); // 添加对象 collection.add(new Person("张三", 23, 5000d)); // 当认为两个对象属性一致,相等时候,需重写hashCode 和 equals方法 System.out.println(collection.contains(new Person("张三", 23, 5000d))); System.out.println("-------"); collection.add(null); Collection<String> collection1 = new ArrayList<>(); collection1.add("嘻嘻"); collection1.add("?"); // 求两个集合的交集(只保留collection1存在的元素) collection.retainAll(collection1); System.out.println(collection); // 清空元素 collection.clear(); System.out.println(collection); }
三、List接口
有序列表,允许存放重复的元素。
实现类:
- ArrayList:数组实现,查询快,增删慢,轻量级;(线程不安全)
- LinkedList:双向链表实现,增删快,查询慢 (线程不安全)
- Vector:数组实现,重量级 (线程安全、使用少)
ArrayList:底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。
ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。
LinkedList:LinkedList是采用双向循环链表实现的。
LinkedList的底层是一种双向循环链表。双向循环链表的查询效率低但是增删效率高。经常用在增删操作较多而查询操作很少的情况下。利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-ended queue )。 它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等。
Vector:与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。
结论:
在考虑并发的情况下用Vector(保证线程的安全)。在不考虑并发的情况下用ArrayList(不能保证线程的安全)。
List是列表类型,以线性方式存储对象,自身的方法都与索引有关,个别常用方法如下。
方法 | 返回值 | 功能描述 |
add(int index, Object obj) | void | 用来向集合中的指定索引位置添加对象,集合的索引位置从0开始,其他对象的索引位置相对向后移一位 |
set(int index, E element) | Object | 用指定元素替换列表中指定位置的元素,返回以前在指定位置的元素 |
indexOf(Object obj) | int | 返回列表中对象第一次出现的索引位置,如果集合中不包含该元素则返回-1 |
lastIndexOf(Object obj) | int | 返回列表中对象最后一次出现的索引位置,如果集合汇总不包含该元素则返回-1 |
listIterator() | ListIterator | 用来获得一个包含所有对象的ListIterator迭代器 |
四、Set接口
无序集合,不允许存放重复的元素,允许使用null元素。对 add()、equals() 和 hashCode() 方法添加了限制。
Set的实现:HashSet、LinkHashSet和TreeSet。
HashSet类直接实现了Set接口,其底层其实是包装了一个HashMap去实现的。HashSet采用HashCode算法来存取集合中的元素,因此具有比较好的读取和查找性能。
HashSet的特征:
- 不能保证元素插入的顺序,而且元素在以后的顺序中也可能变化(这是由HashSet按HashCode存储对象(元素)决定的,对象变化则可能导致HashCode变化)
- HashSet是线程非安全的
- HashSet元素值可以为NULL
HashSet常用方法:
方法 | 返回值 | 功能描述 |
add(Object obj) | boolean | 若集合中尚存在未指定的元素,则添加此元素 |
addAll(Collection col) | boolean | 将参数集合中所有元素添加到集合的尾部 |
remove(Object obj) | boolean | 将指定的参数对象移除 |
clear() | void | 移除此Set中的所有元素 |
iterator() | Iterator | 返回此Set中的元素上进行迭代的迭代器 |
size() | int | 返回此Set集合中的所有元素数 |
isEmpty() | boolean | 如果Set不包含元素,则返回true |
实现Set接口的HashSet,依靠HashMap来实现的。 我们应该为要存放到散列表的各个对象定义hashCode()和equals()。
哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。
当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。
总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。
2. LinkHashSet
HashSet还有一个子类LinkedHashSet,LinkedHashSet集合也是根据元素hashCode值来决定元素存储位置,但它同时使用链表维护元素的次序,这样使的元素看起来是以插入的顺序保存的。也就是说当遍历LinkedHashSet集合里的元素时,HashSet将会按元素的添加顺序来访问集合里的元素。
LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能,但是在迭代访问Set里的全部元素时,将有很好的性能,因为它以列表来维护内部顺序。
总结:LinkedHashSet与HashSet的不同之外在于,后者维护着一个运行于所有条目的双重链接列表,存储的数据是有序的。另外在操作上与父类HashSet相同,直接调用父类的方法即可。
3.TreeSet
- Comparator comparator(); //返回当前Set使用的Comparator,或者返回null,表示以自然方式排序。
- Object first(); //第一个;返回集合中的第一个元素。
- Object last(); //最后一个;返回集合中的最后一个元素。
- Object lower(Object o); //前一个;返回集合中位于指定元素之前的元素(即小于指定元素的最大元素,参考元素不需要是TreeSet的元素)。
- Object higher(Object o); //后一个;返回集合中位于指定元素之后的元素(即大于指定元素的最小元素,参考元素不需要是TreeSet的元素)。
- SortedSet subSet(fromElement, toElement); //返回此Set的子集合,范围从fromElement(包含)到toElement(不包含)。
- SortedSet headSet(toElement); //返回此set的子集,由小于toElement的元素组成。
- SortedSet tailSet(fromElement); //返回此set的子集,由大于或等于fromElement的元素组成。
public class Test {
public static void main(String[] args){
TreeSet<Integer> nums = new TreeSet<Integer>();
nums.add(3);
nums.add(1);
nums.add(5);
nums.add(-9);
//1.返回第一个元素
Integer first = nums.first();
//打印结果为-9
System.out.println(first);
//2.返回最后一个元素
Integer last = nums.last();
//打印结果为5
System.out.println(last);
//3.返回上一个
Integer lower = nums.lower(2);
//打印结果为1
System.out.println(lower);
//4.返回下一个
Integer higher = nums.higher(2);
//打印结果为3
System.out.println(higher);
//5.返回小于3的子集,不包含3
SortedSet<Integer> headSet = nums.headSet(3);
//打印结果[-9, 1]
System.out.println(headSet);
//6.返回大于等于3的子集,包含3
SortedSet<Integer> tailSet = nums.tailSet(3);
//打印结果[3, 5]
System.out.println(tailSet);
//7.打印整个集合结果为[-9, 1, 3, 5]
System.out.println(nums);
}
}
根据上面程序的运行结果可看出,TreeSet并不是根据元素的插入顺序进行排序,而是根据元素实际值来进行排序的。
与HashSet集合采用的hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构对元素进行排序。
TreeSet支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet采用自然排序。
1) 自然排序
Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现该接口的类必须实现该方法,实现了该接口的类的对象就可以比较大小了。当一个对象调用该方法与另一个对象进行比较,例如obj1.compareTo(obj2); 如果该方法返回0,则表明这两个对象相等;如果该方法返回一个正整数,则表明obj1大于obj2;如果该方法返回一个负整数,则表明obj1小于obj2。
Java的一些常用类已经实现了Comparable接口,并提供了比较大小的标准, 下面是实现了Comparable接口的常用类:
- BigDecimal、BigInteger以及所有数值型对应包装类:按它们对象的数值大小进行比较。
- Character :按字符的Unicode值进行比较。
- Boolean : true对应的包装类实例大于false对应的包装类实例。
- String : 按字符串中字符的Unicode值进行比较。
- Date、Time : 后面的时间、日期比前面的日期时间大。
如果试图把一个对象添加进TreeSet时,则该对象的类必须实现Comparable接口,否则程序将会抛出ClassCastException异常。代码如下:
public class Test {
public static void main(String[] args){
TreeSet<Person> persons = new TreeSet<Person>();
persons.add(new Person());
System.out.println(persons);
}
}
2) 定制排序
TreeSet的自然排序是根据集合元素的大小,TreeSet将它们以升序排列。如果需要完成定制排序,例如以降序排列,则可以使用Comparator接口的帮助。该接口里包含了一个int compare(T o1, T o2)方法,该方法用于比较o1、o2的大小:如果该方法返回正整数,则表明o1大于o2;如果该方法返回0,则表明o1等于o2;如果该方法返回负整数,则表明o1小于o2。
如下所示:如果需要实现定制排序(我们这实现倒序),则需要在创建TreeSet集合对象时,并提供一个Comparator对象与该TreeSet集合关联,由该Comparator对象负责集合元素的排序逻辑。
class Person{
Integer age;
public Person(int age){
this.age = age;
}
@Override
public String toString() {
return "Person [age=" + age + "]";
}
}
public class Test {
public static void main(String[] args){
TreeSet<Person> persons = new TreeSet<Person>(new Comparator<Person>(){
@Override
public int compare(Person o1, Person o2) {
if(o1.age > o2.age){
return -1;
}else if(o1.age == o2.age){
return 0;
}else{
return 1;
}
}
});
persons.add(new Person(2));
persons.add(new Person(5));
persons.add(new Person(6));
//打印结果为[Person [age=6], Person [age=5], Person [age=2]]倒序
System.out.println(persons);
}
}
上面程序创建了一个Compartor接口的匿名内部类对象,该对象负责persons集合的排序。所以当我们把Person对象添加到persons集合中时,无须Person类实现Comparable接口,因为此时TreeSet无须通过Person对象来比较大小,而是由与TreeSet关联的Compartor对象来负责集合元素的排序。
五、Map
Map提供了一组键值的映射。其中存储的每个对象都有一个相应的关键字(key),关键字决定了对象在Map中的存储位置。key是唯一的,每个key只能映射一个value。
Map 接口主要有两个实现类:HashMap 类和 TreeMap 类。其中,HashMap 类按哈希算法来存取键对象,而 TreeMap 类可以对键对象进行排序。
主要实现类:
HashMap、TreeMap、LinkedHashMap、Hashtable等
- HashMap:键值对,key不能重复,但是value可以重复;key的实现就是HashSet;value对应着放;允许null的键或值;
- Hashtable:线程安全的,不允许null的键或值;
- Properties::key和value都是String类型,用来读配置文件;
- TreeMap:对key排好序的Map; key 就是TreeSet, value对应每个key; key要实现Comparable接口或TreeMap有自己的构造器;
- LinkedHashMap: 此实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。存储的数据是有序的。
主要方法:
put方法:将指定的键与值对应起来,并添加到集合中
方法返回值为键所对应的值
使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;
使用put方法时,若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。
get方法:获取指定键(key)所对应的值(value)
remove方法:根据指定的键(key)删除元素,返回被删除元素的值(value)。
public class MapDemo {
public static void main(String[] args) {
//创建Map对象
Map<String, String> map = new HashMap<String,String>();
//给map中添加元素
map.put("星期一", "Monday");
map.put("星期日", "Sunday");
System.out.println(map); // {星期日=Sunday, 星期一=Monday}
//当给Map中添加元素,会返回key对应的原来的value值,若key没有对应的值,返回null
System.out.println(map.put("星期一", "Mon")); // Monday
System.out.println(map); // {星期日=Sunday, 星期一=Mon}
//根据指定的key获取对应的value
String en = map.get("星期日");
System.out.println(en); // Sunday
//根据key删除元素,会返回key对应的value值
String value = map.remove("星期日");
System.out.println(value); // Sunday
System.out.println(map); // {星期一=Mon}
}
}
1. HashMap
- Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许重复,但允许值重复。
- HashMap 是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。
- HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;
- HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。
当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法(如果忘记,请回顾HashSet存放自定义对象)。
如果要保证map中存放的key和取出的顺序一致,可以使用LinkedHashMap集合来存放。
2. TreeMap
与HashMap相比,TreeMap是一个能比较元素大小的Map集合,会对传入的key进行了大小排序。其中,可以使用元素的自然顺序,也可以使用集合中自定义的比较器来进行排序;
不同于HashMap的哈希映射,TreeMap底层实现了树形结构,至于具体形态,你可以简单的理解为一颗倒过来的树---根在上--叶在下。如果用计算机术语来说的话,TreeMap实现了红黑树的结构,形成了一颗二叉树。
TreeMap具有如下特点:
- 不允许出现重复的key;
- 可以插入null键,null值;
- 可以对元素进行排序;
- 无序集合(插入和遍历顺序不一致);
//TreeMap基本操作
public class TreeMapTest {
public static void main(String[] agrs){
//创建TreeMap对象:
TreeMap<String,Integer> treeMap = new TreeMap<String,Integer>();
System.out.println("初始化后,TreeMap元素个数为:" + treeMap.size());
//新增元素:
treeMap.put("hello",1);
treeMap.put("world",2);
treeMap.put("my",3);
treeMap.put("name",4);
treeMap.put("is",5);
treeMap.put("jiaboyan",6);
treeMap.put("i",6);
treeMap.put("am",6);
treeMap.put("a",6);
treeMap.put("developer",6);
System.out.println("添加元素后,TreeMap元素个数为:" + treeMap.size());
//遍历元素:
Set<Map.Entry<String,Integer>> entrySet = treeMap.entrySet();
for(Map.Entry<String,Integer> entry : entrySet){
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println("TreeMap元素的key:"+key+",value:"+value);
}
//获取所有的key:
Set<String> keySet = treeMap.keySet();
for(String strKey:keySet){
System.out.println("TreeMap集合中的key:"+strKey);
}
//获取所有的value:
Collection<Integer> valueList = treeMap.values();
for(Integer intValue:valueList){
System.out.println("TreeMap集合中的value:" + intValue);
}
//获取元素:
Integer getValue = treeMap.get("jiaboyan");//获取集合内元素key为"jiaboyan"的值
String firstKey = treeMap.firstKey();//获取集合内第一个元素
String lastKey =treeMap.lastKey();//获取集合内最后一个元素
String lowerKey =treeMap.lowerKey("jiaboyan");//获取集合内的key小于"jiaboyan"的key
String ceilingKey =treeMap.ceilingKey("jiaboyan");//获取集合内的key大于等于"jiaboyan"的key
SortedMap<String,Integer> sortedMap =treeMap.subMap("a","my");//获取集合的key从"a"到"jiaboyan"的元素
//删除元素:
Integer removeValue = treeMap.remove("jiaboyan");//删除集合中key为"jiaboyan"的元素
treeMap.clear(); //清空集合元素:
//判断方法:
boolean isEmpty = treeMap.isEmpty();//判断集合是否为空
boolean isContain = treeMap.containsKey("jiaboyan");//判断集合的key中是否包含"jiaboyan"
}
}
1)使用元素自然排序
在使用自然顺序排序时候,需要区分两种情况:一种是Jdk定义的对象,一种是我们应用自己定义的对象。
public class SortedTest implements Comparable<SortedTest> {
private int age;
public SortedTest(int age){
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//自定义对象,实现compareTo(T o)方法:
public int compareTo(SortedTest sortedTest) {
int num = this.age - sortedTest.getAge();
//为0时候,两者相同:
if(num==0){
return 0;
//大于0时,传入的参数小:
}else if(num>0){
return 1;
//小于0时,传入的参数大:
}else{
return -1;
}
}
}
public class TreeMapTest {
public static void main(String[] agrs){
//自然顺序比较
naturalSort();
}
//自然排序顺序:
public static void naturalSort(){
//第一种情况:Integer对象
TreeMap<Integer,String> treeMapFirst = new TreeMap<Integer, String>();
treeMapFirst.put(1,"jiaboyan");
treeMapFirst.put(6,"jiaboyan");
treeMapFirst.put(3,"jiaboyan");
treeMapFirst.put(10,"jiaboyan");
treeMapFirst.put(7,"jiaboyan");
treeMapFirst.put(13,"jiaboyan");
System.out.println(treeMapFirst.toString());
//第二种情况:SortedTest对象
TreeMap<SortedTest,String> treeMapSecond = new TreeMap<SortedTest, String>();
treeMapSecond.put(new SortedTest(10),"jiaboyan");
treeMapSecond.put(new SortedTest(1),"jiaboyan");
treeMapSecond.put(new SortedTest(13),"jiaboyan");
treeMapSecond.put(new SortedTest(4),"jiaboyan");
treeMapSecond.put(new SortedTest(0),"jiaboyan");
treeMapSecond.put(new SortedTest(9),"jiaboyan");
System.out.println(treeMapSecond.toString());
}
}
在自然顺序比较中,需要让被比较的元素实现Comparable接口,否则在向集合里添加元素时报:"java.lang.ClassCastException: com.jiaboyan.collection.map.SortedTest cannot be cast to java.lang.Comparable"异常;
这是因为在调用put()方法时,会将传入的元素转化成Comparable类型对象,所以当你传入的元素没有实现Comparable接口时,就无法转换,遍会报错;
2)使用自定义比较器排序
使用自定义比较器排序,需要在创建TreeMap对象时,将自定义比较器对象传入到TreeMap构造方法中;自定义比较器对象,需要实现Comparator接口,并实现比较方法compare(T o1,T o2);值得一提的是,使用自定义比较器排序的话,被比较的对象无需再实现Comparable接口了。
public class SortedTest {
private int age;
public SortedTest(int age){
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class SortedTestComparator implements Comparator<SortedTest> {
//自定义比较器:实现compare(T o1,T o2)方法:
public int compare(SortedTest sortedTest1, SortedTest sortedTest2) {
int num = sortedTest1.getAge() - sortedTest2.getAge();
if(num==0){//为0时候,两者相同:
return 0;
}else if(num>0){//大于0时,后面的参数小:
return 1;
}else{//小于0时,前面的参数小:
return -1;
}
}
}
public class TreeMapTest {
public static void main(String[] agrs){
//自定义顺序比较
customSort();
}
//自定义排序顺序:
public static void customSort(){
TreeMap<SortedTest,String> treeMap = new TreeMap<SortedTest, String>(new SortedTestComparator());
treeMap.put(new SortedTest(10),"hello");
treeMap.put(new SortedTest(21),"my");
treeMap.put(new SortedTest(15),"name");
treeMap.put(new SortedTest(2),"is");
treeMap.put(new SortedTest(1),"jiaboyan");
treeMap.put(new SortedTest(7),"world");
System.out.println(treeMap.toString());
}
}
Map常用方法:
- Object put(Object key,Object value):用来存放一个键-值对Map中
- Object remove(Object key):根据key(键),移除键-值对,并将值返回
- void putAll(Map mapping) :将另外一个Map中的元素存入当前的Map中
- void clear() :清空当前Map中的元素
- Object get(Object key) :根据key(键)取得对应的值
- boolean containsKey(Object key) :判断Map中是否存在某键(key)
- boolean containsValue(Object value):判断Map中是否存在某值(value)
- public Set keySet() :返回所有的键(key),并使用Set容器存放
- public Collection values() :返回所有的值(Value),并使用Collection存放
- public Set entrySet() :返回一个实现 Map.Entry 接口的元素 Set
集合遍历:
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; public class TestMap { public static void main(String[] args) { // 初始化,10W次赋值 Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (int i = 0; i < 100000; i++) map.put(i, i); /** 增强for循环,keySet迭代 **/ long start = System.currentTimeMillis(); for (Integer key : map.keySet()) { map.get(key); } long end = System.currentTimeMillis(); System.out.println("增强for循环,keySet迭代 -> " + (end - start) + " ms"); /** 增强for循环,entrySet迭代 */ start = System.currentTimeMillis(); for (Entry<Integer, Integer> entry : map.entrySet()) { entry.getKey(); entry.getValue(); } end = System.currentTimeMillis(); System.out.println("增强for循环,entrySet迭代 -> " + (end - start) + " ms"); /** 迭代器,keySet迭代 **/ start = System.currentTimeMillis(); Iterator<Integer> iterator = map.keySet().iterator(); Integer key; while (iterator.hasNext()) { key = iterator.next(); map.get(key); } end = System.currentTimeMillis(); System.out.println("迭代器,keySet迭代 -> " + (end - start) + " ms"); /** 迭代器,entrySet迭代 **/ start = System.currentTimeMillis(); Iterator<Map.Entry<Integer, Integer>> iterator1 = map.entrySet().iterator(); Map.Entry<Integer, Integer> entry; while (iterator1.hasNext()) { entry = iterator1.next(); entry.getKey(); entry.getValue(); } end = System.currentTimeMillis(); System.out.println("迭代器,entrySet迭代 -> " + (end - start) + " ms"); } }
汇总:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)