Java--集合框架
目录
前言
一 、Collection接口
1.1 Collection常用方法
1.1.1 添加
1.1.2 判断
1.1.3 删除
1.1.4 其它
1.1.5 iterator()
注意
1.2 子接口:List
1.2.1 List接口常用的方法
1.2.2 List实现不同类的对比
1.3 子接口:Set
1.3.1 Set及其实现类的特点
1.3.2 TreeSet--(使用较少)
二、Map接口
2.1 Map及其实现类对比
2.1.1 Map中的常用方法
2.2 TreeMap、Properties
2.3 练习
2.3.1
2.3.2
三、Collections工具类的使用
3.1 Collections
3.2 常用方法
3.2.1 排序
3.2.2 查找
3.2.3 复制、替换、添加
3.2.5 同步控制
前言
1.Java集合框架体系(java.util包下)
java.util.Collection:存储一个一个的数据
- 子接口:List:存储有序的、可重复的数据("动态"数组)----> ArrayList(主要实现类)、LinkedList、Vector
- 子接口:Set:存储无序的、不可重复的数据(高中学习的集合)----> HashSet(主要实现类)、LinkedHashSet、TreeSet
java.util.Map:存储一对一对的数据(key-value键值对,(x1,y1)、(x2,y2)-->y=f(x),类似于高中的函数)
- HashMap(主要实现类)、LinkedHashMap、TreeMap、Hashtab、Properties
程度把握:
- 层次1:针对于具体特点的多个数据,选择相应的适合的接口的主要实现类,会实例化和调用常用的方法。
- 层次2:区分接口中不同的实现类的区别。
- 层次3:① 针对于常用的实现类,需要熟悉底层的源码 ② 熟悉常见的数据结构
图示:
一 、Collection接口
1.1 Collection常用方法
1.1.1 添加
- add(E obj):添加元素对象到当前集合中
- addAl(Collection other):添加other集合中的所有元素对象到当前集合中,即this =this U otherI
- 注意:add和addAll的区别
1.1.2 判断
- int size():获取当前集合中实际存储的元素个类
- boolean isEmpty():判断当前集合是否为空集台
- boolean contains(object obj):判断当前集合中是否存在一个与obj对象equals返回true的元素
- boolean containsAll(Collection coll):判断coll集合中的元素是否在当前集合中都存在。即coll集合是否是当前集合的“子集”
- boolean equals(object obj):判断当前集合与Object是否相等
1.1.3 删除
- void clear():清空集合元素
- boolean remove(Object obj):从当前集合中删除第一个找到的与obi对象equals返回true的元素,
- boolean removeAll(Collection coll):从当前集合中删除所有与col集合中相同的元素。即this=this-this ∩ coll
- boolean retainAll(Collection coll):从当前集合中删除两个集合中不同的元素,使得当前集合仅保留与coll集合中的元素相同的元素,即当前集合中仅保留两个集的交集,即this = this n coll;
1.1.4 其它
- 0bject[] toArray():返回包含当前集合中所有元素的数组
- hashCode():获取集合对象的哈希值
1.1.5 iterator()
iterator():返回迭代器对象,用于集合遍历
迭代器(Iterator)的作用:用来遍历集合元素的 。
过程:
Iterator iterator =coll.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
对象迭代元素过程图解:
注意
1.集合与数组的相互转换:
- 集合--->数组:toArray()
- 数组--->集合:调用Arrays的静态方法asList(0bject...objs)
2.向Collection中添加元素的要求:
- 元素所属的类一定要重写equals()!
- 原因:因为Collection中的相关方法(比如:contains()/remove())在使用时,要调用元素所在类的equals()。
1.2 子接口:List
1.2.1 List接口常用的方法
插入
- void add(int index,0bject ele):在index位置插入ele元素
- boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
获取
- 0bject get(int index)':获取指定index位置的元素
- List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
获取元素索引
- int index0f(0bject obj):返回obj在集合中首次出现的位置
- int lastIndex0f(0bject obj):返回obj在当前集合中末次出现的位置
删除和替换
- 0bject remove(int index):移除指定index位置的元素,并返回此元素
- 0bject set(int index,0bject ele):设置指定index位置的元素为ele
1.2.2 List实现不同类的对比
java.util.collection:存储一个一个的数据
子接口:List:存储有序的、可重复的数据("动态"数组)
- ArrayList:List的主要实现类;线程不安全的、效率高;底层使用0bject[]数组存储。在添加数据、查找数据时,效率较高;在插入、删除数据时,效率较低
- LinkedList:底层使用双向链表的方式进行存储; 在对集合中的数据进行频繁的删除、插入操作时,建议使用此类。在插入、删除数据时,效率较高;在添加数据、查找数据时,效率较低:
- Vector:List的古老实现类;线程安全的、效率低;底层使用0bject[]数组存储
简单练习:学生信息录入
package List;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;public class ListTest {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);List list = new ArrayList();System.out.println("请输入学生的信息");while(true){System.out.println("1.录入学生信息,0.结束录入");int count = scanner.nextInt();if (count == 0) {break;}System.out.print("请输入学生的姓名:");String name = scanner.next();System.out.print("请输入学生的年龄:");int age = scanner.nextInt();Student s = new Student(name,age);list.add(s);}for (Object o : list) {System.out.println(o.toString());}scanner.close();}
}package List;import java.util.Objects;public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "学生{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}}
1.3 子接口:Set
1.3.1 Set及其实现类的特点
Java.util.Collection:存储一个个的数据
子接口:set:存储无序的、不可重复的数据
- HashSet:主要实现类;底层使用的是HashMap,即使用数组+单向链表+红黑树结构进行存储。(jdk8中)
- LinkedHashSet:是HashSet的子类;在现有的数组+单向链表+红黑树结构的基础上,又添加了一组双向链表,用于记录添加元素的先后顺序。即:我们可以按照添加元素的顺序实现遍历。便于频繁的查询操作。
- Treeset:底层使用红黑树存储。可以按照添加的元素的指定的属性的大小顺序进行遍历。
理解:Set中无序性和不可重复性
无序性: 不等于随机性。
- 根据添加的元素的哈希值,计算的其在数组中的存储位置。此位置不是依次排列的,表现为无序性。
不可重复性:添加到Set中的元素是不能相同的。
- 需要判断hashcode()得到的哈希值以及equals()得到的boolean型的结果。
- 哈希值相同且equals()返回true,则认为元素是相同的。
1.3.2 TreeSet--(使用较少)
1.向Treeset中添加的元素的要求:
- 要求添加到TreeSet中的元素必须是同一个类型的对象,否则会报ClasscastException.
- 添加的元素需要考虑排序:①自然排序 ② 定制排序
2. 判断数据是否相同的标准
- 添加到TreeSet中的元素所在的类不需要重写hashcode()和equals()
- 比较元素大小的或比较元素是否相等的标准就是考虑compareTo()或compare()的返回值。
- 如果compareTo()或compare()的返回值为0,则认为两个对象是相等的。由于TreeSet中不能存放相同的元素,则后一个相等的元素就不能添加到Treeset中。
练习:
/*定义方法如下:public static List duplicateList(List list)要求:① 参数List中只存放Integer的对象在List内去除重复数字值,尽量简单*/import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;public class setTest {public static void main(String[] args) {List list = new ArrayList();list.add(22);list.add(22);list.add(21);list.add(21);list.add(32);list.add(42);list.add(32);list.add(42);List newlist = duplicateList(list);System.out.println(newlist);}public static List duplicateList(List list){HashSet set = new HashSet(list);List list1 = new ArrayList(set);return list1;}}
二、Map接口
2.1 Map及其实现类对比
java.util.Map:存储一对一对的数据(key-value键值对(x1,y1)、(x2,y2)--> y=f(x))
- HashMap:主要实现类;线程不安全的,效率高;可以添加null的key和valve值;底层使用数组+单向链表+红黑树结构存储(jdk8)
- LinkedHashMap:是HashMap的子类;在HashMap使用的数据结构的基础上,增加了一对双向链表,用于记录添加的元素的先后顺序,进而我们在遍历元素时就可以按照添加的顺序显示。开发中,对于频繁的遍历操作,建议使用此类。
- Hashtable:古老实现类;线程安全的,效率低,可以添加nul1的key或valve值;底层使用数组+单向链表结构存储(jdk8)
- TreeMap:底层使用红黑树存储;可以按照添加的key-valve中的key元素的指定的属性的大小顺序进行遍历。需要考虑使用①自然排序 ②定制排序。
- Properties:其key和value都是String类型。常用来处理属性文件。
2.1.1 Map中的常用方法
添加、修改操作:
- 0bject put(0bject key,0bject value):将指定key-value添加到(或修改)当前map对象中
- void putAll(Map m):将m中的所有key-value对存放到当前map中
删除操作:
- 0bject remove(0bject key):移除指定key的key-value对,并返回value
- void clear():清空当前map中的所有数据
元素查询的操作:
- 0bject get(0bject key):获取指定key对应的value
- boolean containsKey(0bject key):是否包含指定的key
- boolean containsValve(0bject valve):是否包含指定的value
- boolean equals(0bject obj):判断当前map和参数对象obj是否相等
长度:
- int size():返回map中key-value对的个数
- boolean isEmpty():判断当前map是否为空
元视图操作的方法:
- Set keySet():返回所有key构成的Set集合
- Collection values():返回所有value构成的Collection集合
- Set entrySet():返所有key-value对构成的Set集合
2.2 TreeMap、Properties
TreeMap的使用
- 底层使用红黑树存储;
- 可以按照添加的key-valve中的key元素的指定的属性的大小顺序进行历
- 需要考虑使用①自然排序 ②定制排序。
- 要求:向TreeMap中添加的key必须是同一个类型的对象。
Hashtable与Properties的使用
- Properties:是Hashtable的子类,其key和valve都是String类型的,常用来处理属性文件
2.3 练习
2.3.1
题目: 歌手,歌曲名称输出
package List;import java.util.*;public class setTest {public static void main(String[] args) {HashMap singer = new HashMap();String singer1 = "周杰伦";ArrayList song1 = new ArrayList();song1.add("夜曲");song1.add("稻香");song1.add("听妈妈的话");song1.add("告白气球");singer.put(singer1,song1);String singer2 = "林俊杰";ArrayList song2 = new ArrayList();song2.add("曹操");song2.add("三国");song2.add("可惜没如果");song2.add("修炼爱情手册");singer.put(singer2,song2);Set set = singer.entrySet();Iterator iterator = set.iterator();while(iterator.hasNext()){Map.Entry entry = (Map.Entry)iterator.next();System.out.println("歌手: "+ entry.getKey());System.out.println("歌曲名称: "+ entry.getValue());}}
}
2.3.2
题目:登记省份和城市信息
package List;import java.util.*;public class setTest {public static void main(String[] args) {Map map = CityMap.model;Set provinces = map.keySet();for (Object province: provinces) {System.out.print(province + "\t\t");}//从键盘中获取省份,判断省份是否存在,并找到所属的城市Scanner scan = new Scanner(System.in);String[] cities;while(true){System.out.print("\n请输入你所在的省份:");String province = scan.next();//获取构成省份的城市的String[]cities = (String[]) map.get(province);if (cities == null ||cities.length == 0) {System.out.println("您输入的省份有误,请重新输入:");}else{break;//输入的省份存在,所以退出循环}}for (int i = 0; i < cities.length; i++) {System.out.print(cities[i] + "\t\t");}System.out.println();l:while(true) {System.out.print("请输入你所在的城市:");String city = scan.next();for (int i = 0; i < cities.length; i++) {if (city.equals(cities[i])) {System.out.println("信息登记完毕!");break l;}}System.out.println("输入的城市有误!请重新输入");}scan.close();}
}class CityMap{public static Map model = new HashMap();static {model.put("北京",new String[]{"北京"});model.put("辽宁",new String[]{"沈阳","盘锦","铁岭","丹东","大连","锦州","营口"});model.put("吉林",new String[]{"长春","延边","吉林","白山","白城","四平","松原"});model.put("河北",new String[]{"承德","沧州","邯郸","邢台","唐山","保定","石家庄"});model.put("河南",new String[]{"郑州","许昌","开封","洛阳","商丘","南阳","新多"});model.put("山东",new String[]{"济南","青岛","日照","临沂","泰安","聊城","德州"});}
}
三、Collections工具类的使用
3.1 Collections
Collections是一个操作Set、List 和Map 等集合的工具类。
注意:
区分Collection和Collections
Collection:集合框架中的用于存储一个一个元素的接口,又分为List和Set等子接口。
Collections:用于操作集合框架的一个工具类。此时的集合框架包括:Set、List、Map
3.2 常用方法
3.2.1 排序
- reverse(List):反转 List 中元素的顺序
- shuffle(List):对 List 集合元素进行随机排序
- sort(List):根据元素的自然顺序对指定List 集合元素按升序排序
- sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
- swap(List,int,int):将 i 处元素和 j 处元素进行交换
代码:
package List;import java.util.*;public class setTest {public static void main(String[] args) {List list = new ArrayList();list.add("Alice");list.add("John");list.add("Emma");list.add("Michael");list.add("Sophia");System.out.println("原始顺序:" + list);// 反转Collections.reverse(list);System.out.println("反转后:" + list);// 洗牌Collections.shuffle(list);System.out.println("洗牌后:" + list);// 自然升序Collections.sort(list);System.out.println("自然升序后:" + list);// 交换Collections.swap(list, 2,4);System.out.println("交换后:" + list);}
}
3.2.2 查找
- binarySearch(List list, Object key):二分查找法,前提是 List 已经排序过了
- max(Collection coll):返回最大元素
- max(Collection coll, Comparator comp):根据自定义比较器,返回最大元素
- min(Collection coll):返回最小元素
- min(Collection coll, Comparator comp):根据自定义比较器,返回最小元素
- fill(List list, Object obj):使用指定对象填充
- frequency(Collection c, Object o):返回指定对象出现的次数
代码:
@Testpublic void test(){List list = new ArrayList();list.add("Alice");list.add("John");list.add("Emma");list.add("Michael");list.add("Sophia");System.out.println("最大元素:" + Collections.max(list));System.out.println("最小元素:" + Collections.min(list));System.out.println("查找的元素出现的次数:" + Collections.frequency(list, "John"));// 没有排序直接调用二分查找,结果是不确定的System.out.println("排序前的二分查找结果:" + Collections.binarySearch(list, "Emma"));Collections.sort(list);// 排序后,查找结果和预期一致System.out.println("排序后的二分查找结果:" + Collections.binarySearch(list, "Emma"));Collections.fill(list, "Alibaba");System.out.println("填充后的结果:" + list);}
3.2.3 复制、替换、添加
void copy(List dest,List src):将src中的内容复制到dest中
boolean replaceAll(List list,0bject oldVal,0bject newVal):使用新值替换 List 对象的所有旧值
addAll(Collection c, T... elements),往集合中添加元素
disjoint(Collection c1, Collection c2),判断两个集合是否没有交集
unmodifiableXxx():返回指定 Xxx的不可修改的视图
3.2.5 同步控制
使用格式
SynchronizedList synchronizedList = Collections.synchronizedList(list);