[笔记] 疯狂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集合,内容很多,很难记住每个类的细节,看完书后要做一下精简版的总结。


相关文章
|
1天前
|
存储 Java 测试技术
杨校老师课堂之Java基础集合专题知识点整理
杨校老师课堂之Java基础集合专题知识点整理
4 0
|
1天前
|
Java
Java集合之map 集合使用
Java集合之map 集合使用
3 0
|
2天前
|
存储 安全 Java
Java集合类是Java编程语言中用于存储和操作一组对象的工具
【6月更文挑战第19天】Java集合类,如`List`、`Set`、`Map`在`java.util`包中,提供高级数据结构。常用实现包括`ArrayList`(快速随机访问)、`LinkedList`(高效插入删除)、`HashSet`(无序不重复)、`TreeSet`(排序)、`HashMap`(键值对)和`TreeMap`(排序映射)。集合动态调整大小,支持对象引用,部分保证顺序。选择合适集合优化性能和数据组织。
8 1
|
3天前
|
Java 开发者
Queue大比拼:为何LinkedList能在众多Java集合中脱颖而出?
【6月更文挑战第18天】**Java的LinkedList作为队列的优势在于其双向链表实现,支持O(1)时间复杂度的首尾操作,适合作为Queue接口的实现。它也是线程不安全的,但在单线程环境下性能优越,并可通过Collections同步化。此外,它的灵活性使其也能胜任栈和双端队列的角色。**
|
4天前
|
存储 安全 算法
Java集合框架详解
Java集合框架详解
|
4天前
|
存储 Java
打破常规!HashSet和TreeSet教你重新认识Java集合的无序与有序
【6月更文挑战第17天】Java集合框架中的Set接口,HashSet无序而TreeSet有序。HashSet基于哈希表,元素插入顺序不可预测,适合快速去重。TreeSet利用红黑树保证有序性,支持自然排序或自定义排序。若需同时无序和有序,可先用HashSet去重,再将元素加入TreeSet,但会牺牲性能。选择时依据对顺序和性能的需求。
|
4天前
|
算法 Java 数据处理
从HashSet到TreeSet,一场Java集合的“不重复”革命!
【6月更文挑战第17天】Java集合框架中的Set接口确保元素唯一,HashSet基于哈希表实现高效查找,不保证顺序;TreeSet使用红黑树保持排序,适用于有序场景。示例展示了HashSet的无重复添加及TreeSet的升序排列。Set是处理唯一性数据的利器。
|
4天前
|
存储 Java 索引
告别Java集合小白!一文读懂List的精髓
【6月更文挑战第17天】Java中的List接口作为有序集合,允许存储和操作有序元素,支持重复值。ArrayList和LinkedList是常见实现类:ArrayList基于数组,适合快速访问但插入删除慢;LinkedList基于链表,插入删除快但访问慢。了解其核心概念、方法及泛型使用,能提升编程效率和代码质量。示例代码展示了添加和访问元素。通过深入学习,可以更好地掌握List的高级用法。
|
4天前
|
Java 测试技术 C++
滚雪球学Java(63):Java高级集合之TreeSet:什么是它,为什么使用它?
【6月更文挑战第17天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
10 0
滚雪球学Java(63):Java高级集合之TreeSet:什么是它,为什么使用它?
|
6天前
|
Java
java集合
摘要:使用`equals`方法可直接比较两个集合是否完全相同,因Java集合类已重写该方法。快速创建集合可采用`Lists.newArrayList()`。
9 3