[笔记] 疯狂JAVA讲义(第3版)第8章 Java集合(二)

简介: [笔记] 疯狂JAVA讲义(第3版)第8章 Java集合(二)

[笔记] 疯狂JAVA讲义(第3版)第8章 Java集合(一):https://developer.aliyun.com/article/1537901

8.4.2 ArrayList和Vector实现类


List的两个实现类。ArrayList和Vector都是基于数组实现的List类,封装了一个动态、可再分配的Object[] 数组。


允许使用initialCapacity参数设置数组长度,当元素超出该长度时,initalCapacity会自动增加。


通常无需关系initalCapacity,但如果要添加大量元素时,可以使用ensureCapacity(int minCapacity)一次性增加(到)initalCapacity。可以减少分配次数,提高性能。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-46jLwn8w-1588248416674)(media/image6.png)]{width=“7.544671916010499in” height=“1.2098359580052493in”}


ArrayList和Vector用法上几乎完全相同,但Vector是一个古老的集合,里面有一些方法名很长的方法。


除此之外,ArrayList是线程不安全的。


Vector还提供一个Stack子类,模拟栈。由于Vector太古老了,不推荐使用Vector类。


8.4.3 固定长度的List


Arrays.asList(Object… a),将一个数组或指个数的对象转换成一个List集合,该集合是Arrays的内部类ArrayList的实例。


Arrays.ArrayList是一个固定长度的List集合,程序只能遍历集合元素,不可增减。


package ch8;
import java.util.Arrays;
import java.util.List;
public class FixedSizeList {
public static void main(String[] args) {
List fixedList = Arrays.asList(“fk java”,“java EE”);
System.out.println(fixedList.getClass());
fixedList.forEach(System.out::println);
}
}

8.5 Queue集合


Queue用于模拟队列。队列是先进先出(FIFO)的容器。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VxVKZt0b-1588248416675)(media/image7.png)]{width=“7.628687664041995in” height=“1.873565179352581in”}


8.5.1 PriorityQueue


Queue的比较标准的实现类。但PriorityQueue保存元素的顺序是按照元素的大小排序的。


因此,并不是按照FIFO原则。


package ch8;
import java.util.PriorityQueue;
public class PriorityQueueTest {
public static void main(String[] args) {
PriorityQueue pq = new PriorityQueue();
pq.offer(6);
pq.offer(-3);
pq.offer(20);
pq.offer(18);


System.out.println(pq); //输出[-3,6,20,18],受到toString()的影响,实际上调用poll()是按从小到大排序的。


System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
}
}

PriorityQueue的排序方式和TreeSet基本一致。


8.5.2 Deque接口和ArrayDeque实现类


Deque是一个双端序列。允许从两端操作数据。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uwrZi1Er-1588248416675)(media/image8.png)]{width=“7.922744969378828in” height=“4.923360673665792in”}


Deque接口提供了一个典型的实现类:ArrayDeque,可以用来实现Stack和Queue。


package ch8;
import java.util.ArrayDeque;
public class ArrayDequeueStack {
public static void main(String[] args) {
ArrayDeque stack = new ArrayDeque();
stack.push(“java”);
stack.push(“javase”);
stack.push(“Android”);
System.out.println(stack);
System.out.println(stack.peek());
System.out.println(stack);
System.out.println(stack.pop());
System.out.println(stack);
}
}
package ch8;
import java.util.ArrayDeque;
public class ArrayDequeQueue {
public static void main(String[] args) {
ArrayDeque queue = new ArrayDeque();
queue.offer(“java”);
queue.offer(“javaee”);
queue.offer(“Android”);
System.out.println(queue);
System.out.println(queue.peek());
System.out.println(queue);
System.out.println(queue.poll());
System.out.println(queue);
}
}


8.5.3 LinkedList实现类


List的实现类,此外,LinkedList还实现了Deque接口。


package ch8;
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList books = new LinkedList();
books.offer(“java”);
books.push(“javaee”);
books.offerFirst(“Android”);
for(int i = 0 ; i < books.size() ; i++) {
System.out.println(books.get(i));
}
System.out.println(books.peekFirst());
System.out.println(books.peekLast());
System.out.println(books.pop());
System.out.println(books);
System.out.println(books.pollLast());
System.out.println(books);
}
}


8.5.4 各种线性表的性能分析


List:线性表接口


ArrayList、LinkedList 两种实现


Queue:队列


Deque:双端队列


一般来说,ArrayList随机访问性能好,LinkedList插入删除时性能好。总体来说,ArrayList性能更好。


List使用使用建议:


遍历:对于ArrayList,使用随机访问 get()方法来遍历;而LinkedList,使用迭代器(Iterator)遍历


线程安全:多线程时,考虑使用Collection将集合包装成线程安全的集合。


8.6 Java 8 增强的Map集合


Map用于保存具有映射关系的数据,Map集合里保存着两组值,一组保存Key,另一组保存Value。


key和value都可以是任何类型的数据,key不能重复。


key -value一一对应。


@key集存储方式和Set存储形式完全相同。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4PWWffom-1588248416677)(media/image9.png)]{width=“9.317416885389326in” height=“6.998565179352581in”}


package ch8;
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
Map map = new HashMap();
//放入key-value对,value可以重复,如果放入重复的key,新的value值会覆盖原来的value
map.put(“疯狂Java讲义”,109);
map.put(“疯狂IOS讲义”,10);
System.out.println(map);
//判断是否包含指定key
System.out.println(“包含值 疯狂IOS讲义的key:”+map.containsKey(“疯狂IOS讲义”));
//判断是否包含指定value
System.out.println(“包含值为99的value:”+map.containsValue(10));
//获取key集合,通过遍历key遍历key-value对
for(Object key : map.keySet()) {
System.out.println(key+"–>"+map.get(key));
}
map.remove(“疯狂IOS讲义”);//根据key来删除key-value对
System.out.println(map);
}
}

8.6.1 java8为Map新增的方法


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ngbFHAIz-1588248416679)(media/image10.png)]{width=“8.065573053368329in” height=“7.191802274715661in”}


package ch8;
import java.util.HashMap;
import java.util.Map;
public class MapTest2 {
public static void main(String[] args) {
Map map = new HashMap();
//放入key-value对
map.put(“疯狂java”,109);
map.put(“疯狂IOS”, 99);
map.put(“疯狂Ajex”, 79);
map.replace(“疯狂XML”, 66); //替换key为"疯狂XML"的value。但由于原map没有此key,所以不会替换。也不会新加键值对
System.out.println(map);
//覆盖原value, 变成oldV + 10
map.merge(“疯狂IOS”, 10,
(oldV,param)->(Integer)oldV + (Integer)param);
System.out.println(map);
//当key为java对应的value为null或不存在时,使用计算的结果作为新value
map.computeIfAbsent(“java”, (key)->((String)key).length());
System.out.println(map);
//key对应value存在时,计算新value
map.computeIfPresent(“java”, (key,value)->(Integer)value*(Integer)value);
System.out.println(map);
}
}


8.6.2 java 8改进的HashMap和Hashtable实现类


Hashtable是一个古老的Map实现类,不推荐使用。


为了能够在HashMap中存储对象,作为key的对象必须实现hashCode()和equals()方法。


8.6.3 LinkedMap实现类


使用双向链表维护key的次序。


package ch8;
import java.util.LinkedHashMap;
public class LinkedHashMapTest {
public static void main(String[] args) {
LinkedHashMap scores = new LinkedHashMap();
scores.put(“语文”,90);
scores.put(“数学”,92);
scores.put(“英语”,80);
scores.forEach((key,value)->System.out.println(key+"–>"+value));
}
}


8.6.4 使用Properties读取属性文件


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qyuatnOx-1588248416681)(media/image11.png)]{width=“8.073975284339458in” height=“4.318442694663167in”}


package ch8;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
public class PropertiesTest {
public static void main(String[] args)throws Exception {
Properties props = new Properties();
//添加属性
props.setProperty(“username”, “yuke”);
props.setProperty(“password”, “123456”);
//保存至a.ini文件
props.store(new FileOutputStream(“a.ini”),“comment line”);
Properties p2 = new Properties();
p2.setProperty(“gender”, “male”);
//将a.ini中key-value追加到p2中
p2.load(new FileInputStream(“a.ini”));
System.out.println(p2);
}
}

8.6.5 SortedMap接口和TreeMap实现类。


TreeMap存储key-value时,根据key进行排序,保证有序。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7B5lp8Qi-1588248416681)(media/image12.png)]{width=“8.157991032370953in” height=“7.8471303587051615in”}


8.6.6 WeakHashMap实现类


类似HashMap,但WeakHashMap只保留对实际对象的弱引用,对象在垃圾回收时可能会被回收。


8.6.7 IdentityHashMap实现类


类似HashMap,但处理相等的key时,仅在key1==key2严格相等时,才认为相等。而HashMap只判断equals()和hashCode()方法。


8.6.8 EnumMap实现类


创建EnumMap时必须指定一个枚举类。


8.6.9 各Map实现类的性能分析


对于一般场景,应该考虑使用HashMap.


如果需要排序,则可以考虑TreeMap。


8.7 HashSet和HashMap的性能选项


HashSet类采用hash算法决定元素存储位置,并通过hash算法来控制集合的大小;


hash表里可以存储元素的位置称为"桶(bucket)",通常情况下,单个"桶"存放一个元素,此时有最好的性能。


hash算法根据hashCode值计算出"桶"的位置,接着从"桶"中取出元素。


但发生hash冲突时,单个桶会存储多个元素,这些元素以链表形式存储,必须按顺序搜索。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7XLY8aPY-1588248416682)(media/image13.png)]{width=“3.1758191163604548in” height=“1.6887292213473315in”}


HashSet、HashMap的hash表中都包含如下属性:


容量(capacity):桶数量


初始化容量(initial capacity):


尺寸(size):当前数量


负载因子(load factor):负载因子等于size/capacity,负载因子=0,代表空,负载因子=0.5,代表半满。


负载极限:0~1,当负载因子达到负载极限时,hash表会自动成倍增加容量。默认值0.75.


8.8 操作集合类的工具类:Collections


Collections类提供对集合元素排序、查询、修改等操作。


8.8.1 排序操作


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x0VXM5RJ-1588248416683)(media/image14.png)]{width=“7.586679790026246in” height=“2.1424179790026248in”}


package ch8;
import java.util.ArrayList;
import java.util.Collections;
public class SortTest {
public static void main(String[] args) {
ArrayList nums = new ArrayList();
nums.add(2);
nums.add(-5);
nums.add(3);
nums.add(0);
System.out.println(nums);
Collections.reverse(nums);//翻转
System.out.println(nums);
Collections.sort(nums);//排序
System.out.println(nums);
Collections.shuffle(nums);//随机顺序
System.out.println(nums);
}
}


8.8.2 查找、替换操作


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gs5PfYPQ-1588248416684)(media/image15.png)]{width=“7.947950568678915in” height=“3.94876968503937in”}


package ch8;
import java.util.ArrayList;
import java.util.Collections;
public class SearchTest {
public static void main(String[] args) {
ArrayList nums = new ArrayList();
nums.add(2);
nums.add(-5);
nums.add(3);
nums.add(0);
System.out.println(nums);
System.out.println(Collections.max(nums));
System.out.println(Collections.min(nums));
Collections.replaceAll(nums, 0, 1);//替换
System.out.println(nums);
System.out.println(Collections.frequency(nums, -5));
Collections.sort(nums);//排序
System.out.println(nums);
System.out.println(Collections.binarySearch(nums, 3));//二分查找,要求是排序好的
}
}


8.8.3 同步控制


Collections类提供多个synchronizedXxx()方法,可以将指定集合包装成线程同步的集合。


如:


List list = Collections.synchronizedList(new ArrayList());


8.8.4 设置不可变集合


Collections类提供三类方法来返回一个不可变的集合:


emptyXxx(): 返回一个不可变的Xxx


singletonXxx():返回一个只包含指定对象的xx


unmodifiableXxx():返回指定对象的不可变视图。


package ch8;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class UnmodifiableTest {
public static void main(String[] args) {
List unmodifiableList = Collections.emptyList();
Set unmodifiableSet = Collections.singleton(“疯狂Java讲义”);
Map scores = new HashMap();
scores.put(“语文”,100);
scores.put(“数学”,99);
Map unmodifiableMap = Collections.unmodifiableMap(scores);
}
}


8.9 繁琐的接口:Enumeration 很古老,建议略过,当然我只是建议


//小结,Java集合,内容很多,很难记住每个类的细节,看完书后要做一下精简版的总结。


相关文章
|
30天前
|
存储 Java 开发者
【潜意识Java】深入详细理解分析Java中的toString()方法重写完整笔记总结,超级详细。
本文详细介绍了 Java 中 `toString()` 方法的重写技巧及其重要
51 10
【潜意识Java】深入详细理解分析Java中的toString()方法重写完整笔记总结,超级详细。
|
30天前
|
前端开发 JavaScript Java
Java构建工具-maven的复习笔记【适用于复习】
这篇文档由「潜意识Java」创作,主要介绍Maven的相关知识。内容涵盖Maven的基本概念、作用、项目导入步骤、依赖管理(包括依赖配置、代码示例、总结)、依赖传递、依赖范围以及依赖的生命周期等七个方面。作者擅长前端开发,秉持“得之坦然,失之淡然”的座右铭。期待您的点赞、关注和收藏,这将是作者持续创作的动力! [个人主页](https://blog.csdn.net/weixin_73355603?spm=1000.2115.3001.5343)
40 3
|
2月前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
53 3
|
2月前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
60 5
|
2月前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
87 0
|
2月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
2月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
3月前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
72 4
|
3月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
59 2

热门文章

最新文章