赞
踩
本人刚刚复习完集合框架,写在这里以便于记忆,还有自己的一些总结,与你们分享。
说到集合,我们首先得知道什么是集合。
集合其实就是java提供的一个容器,用来存放数据的容器
之前我们所学的数组,也可以存放数据,但是数组的长度是固定的,不方便我们使用,于是便有了集合。
再者,数组中存储的元素都是同一类型的元素,只可以存储一些基本的数据类型(int、String、Float、Char、…)
但是集合中存储的都是对象,而且对象的类型还可以不一致。
再开发中,一般使用对象居多的时候,我们可以选用集合来进行存储
再学习集合之前,我们需要先知道集合框架,如下图;
要想掌握集合的全部用法,应该从顶层向下学习
也就是,先学习Collection接口中的方法,他的方法子类都可以使用
在Collection接口中,定义的是所有单列集合中共性的方法,所有的单列集合都可以使用。
在Collection接口中,常用的共性方法用;
public class demo1 { public static void main(String[] args) { Collection coll = new ArrayList(); //面向对象中的多态 /** * add添加元素 */ coll.add(1); coll.add("abc"); coll.add(1.23); coll.add("张三"); System.out.println(coll); System.out.println("__________________________"); /** * remove删除元素 */ coll.remove(1); System.out.println(coll); System.out.println("__________________________"); /** * contains判断当前集合中是否包含指定的对象 */ boolean a = coll.contains(1.23); System.out.println(a);//如果存在就返回true,否则返回false System.out.println("__________________________"); /** * isEmpty判断当前集合是否为空 */ boolean b = coll.isEmpty(); System.out.println(b);//如果为空就返回true,否则返回false System.out.println("__________________________"); /** * size返回集合中元素的个数 */ Integer i = coll.size();//推荐用Integer,不建议用int System.out.println(i); System.out.println("__________________________"); /** * toArray把集合中的元素,存储到数组中 */ Object[] obj = coll.toArray(); System.out.println(obj);//[Ljava.lang.Object;@4554617c 这个数组的地址值 for (Object o : obj) { System.out.println(o); //输出遍历的数组 abc 1.23 张三 } System.out.println("__________________________"); /** * clear 清空元素 */ coll.clear(); System.out.println(coll); /** * 判断集合是否为空 */ boolean d =coll.isEmpty(); System.out.println(d);//true } }
输出结果;
注意:Collection接口中没有带索引的方法;
在使用过程中,顶层不是接口就是抽象类,无法创建对象使用,需要使用底层的子类创建对象使用
在遍历集合中,还需要涉及到一个Iterator接口,也就是迭代。
迭代的概念;Collection集合元素的通用获取方式,再取元素之前要先判断集合中有没有元素,如果有,就把这个元素取出来,继续在进行判断,如果还有就再取出来,一直把集合中的所有元素取出,这种取出方式专业术语就叫做迭代
其中有两个 比较常用的方法;
(1),boolean hasNext();如果仍有元素就可以迭代,返回的就是true,判断集合中还有没有下一个元素,有就返回true,没有就返回false
(2),E next()返回迭代的下一个元素;取出集合中的下一个元素
Iterator也是一个接口,我们无法直接使用,需要使用Iterator接口的实现类。
在Collection接口中有一个方法,Iterator(),这个方法的返回值就是迭代器的实现类
看代码
Collection coll = new ArrayList(); //面向对象中的多态 /** * add添加元素 */ coll.add(1); coll.add("abc"); coll.add(1.23); coll.add("张三"); System.out.println(coll); Iterator it = coll.iterator(); boolean a = it.hasNext(); System.out.println(a);//输出结果为true Object obj =it.next(); System.out.println(obj);//输出结果为1 } }
也可以添加一个while循环,遍历出集合元素
Iterator it = coll.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.println(obj);//输出结果;1 abc 1.23 张三
}
也可以添加一个for循环
for(Iterator it = coll.iterator();it.hasNext();){
Object obj = it.next();
System.out.println(obj);//输出1 abc 1.23 张三
}
原理分析
还有种遍历集合的方式,高级for循环(也叫增强for循环)
增强for循环(也称为for each循环)是jdk 1.5以后出来的一个高级的for循环,专们用来遍历数组,它的内部原理其实是Iterator迭代器,所以在遍历的过程中,不能对集合进行增删操作;
格式;
for(集合/数组的数据类型 变量名:集合名/数组名){
sout(变量名)
}
上述代码中,集合转为数组部分,就是用的增强for循环
注意;
新for循环必须有被遍历的目标,目标只能是Collection或者是数组,新式for仅仅作为遍历操作出现。
在正式的学习集合之前,还要掌握一些泛型的基本知识。(在这里不一一列举)
直接看List接口;
List接口是继承的Collection接口,所以Collection接口中的方法,在List接口中也适用。
List接口的特点;
public class demo1 { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("a"); System.out.println(list); //添加元素 list.add(2,"hbsi"); System.out.println(list); //移除元素 String b = list.remove(2); System.out.println(b); System.out.println(list); //返回指定元素 String v = list.get(1); System.out.println(v); System.out.println(list); //替换元素 String a = list.set(4,"asc"); System.out.println(a); System.out.println(list); //遍历元素 for (int i = 0; i < list.size(); i++) { String x = list.get(i); System.out.println(x); } //迭代器 Iterator<String> it = list.iterator(); while(it.hasNext()){ String s = it.next(); System.out.println(s); } //foreach for (String s : list) { System.out.println(s); } list.get(6);//越界异常 IndexOutOfBoundsException } }
List集合的子类;
ArrayList集合与LinkedList集合 都实现了List接口,List接口中的方法,他们都可以用。
ArrayList集合:
他的底层是数组,特点:增删快,查询慢。
ArrayList集合中的方法大部分大继承与List接口
LinkedList集合;
(1),底层是链表结构(双向链表),查询慢,增删快。
(2),里边包含了大量操作首尾元素的方法。
什么是双向链表?
图解
此集合中常用的方法;
-public void addFirst(E e) :将指定元素插入此列表的开头。
-public void addLast(E e) :将指定元素添加到此列表的结尾。
-public E getFirst() :返回此列表的第一个元素。
-public E getLast() :返回此列表的最后一个元素。
-public E removeFirst() :移除并返回此列表的第一个元素。
-public E removeLast() :移除并返回此列表的最后一个元素。
-public E pop() :从此列表所表示的堆栈处弹出一个元素。
-public void push(E e) :将元素推入此列表所表示的堆栈。
-public boolean isEmpty() :如果列表不包含元素,则返回true。
代码演示;
public class LinkedListDemo { public static void main(String[] args) { LinkedList<String> link = new LinkedList<String>(); //添加元素 link.addFirst("abc1"); link.addFirst("abc2"); link.addFirst("abc3"); System.out.println(link); // 获取元素 System.out.println(link.getFirst()); System.out.println(link.getLast()); // 删除元素 System.out.println(link.removeFirst()); System.out.println(link.removeLast()); while (!link.isEmpty()) { //判断集合是否为空 System.out.println(link.pop()); //弹出集合中的栈顶元素 } System.out.println(link); } }
LinkedList集合也可以作为堆栈,队列的结构使用;
下一个集合;
Vector集合 底层也是数组。(JDK1.0开始)
(由于线程安全,查询速度慢,JDK1.2以后被ArrayList取代)
方法参要;(了解即可)
其中的方法大部分与ArrayList大同小异
但是他的接口Serializable很重要(序列化)
Set接口
java.util.Set接口 extends Collection接口;
Set接口的特点;
(1)不允许存储重复的元素
(2)没有索引,也没有带索引的方法,也不可以使用普通的For循环遍历
(3)Set接口中,元素无序
HashSet集合;
java.util.HashSet集合 implements Set 接口
特点;
(1),不如许存储重复的元素
(2),没有索引,没有带索引的方法,也不能使用普通的for循环遍历
(3),是一个无序集合,存储元素和取出元素的顺序有可能不一致
(4),底层是哈希表结构(查询的速度非常快)
代码展示;
package Day6_22; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class Demo01 { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("a"); set.add("b"); set.add("c"); set.add("a"); //迭代器遍历 Iterator<String> it = set.iterator(); while(it.hasNext()){ String b =it.next(); System.out.println(b); } //for增强遍历 for (String s : set) { System.out.println(s); } } }
HashSet集合存储数据的结构(哈希表)
(1),首先需要认识什么是哈希值
哈希值:是一个十进制的整数,由系统随机的给出
(其实就是对象的地址值,是一个逻辑地址,模拟出来的地址,并不是数据实际存储的物理地址)
(2),在Object顶级父类中,有一个方法,可以获取对象的哈希值
int hashCode();返回的就是int类型的对象的哈希值
获取hashCode的代码实现;
其中有两个比较特殊,“重地”与“通话”这两个字符串的哈希值是相等的。
HashSet集合存储数据的结构(哈希表)简述
在JDK1.8版本之前:哈希表=数组+链表
在JDK1.8之后(包含1.8)之后;
哈希表=数组+链表/哈希表=数组+红黑树
特点:查询速度快
初始容量:16
数组结构:(把元素进行分组,(相同哈希值的元素是一组)链表/红黑树结构把相同哈希值的元素连接到一起)
图解(来源网络)
基本代码实现
public class demo4 {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("abc"); //这是一个重复元素,(不允许存储重复元素)
set.add("abc");
set.add("重地");
set.add("通话");
System.out.println(set);//[重地, 通话, abc]
System.out.println("abc".hashCode());
}
原理代码分析,(图解,来源网络)
HashSet存储自定义类型的元素
需要重写对象中hasCode和equals方法,建立自己的比较方式,才可以保证HashSet集合中的对象唯一
图解(来源网络)
下一个集合;
LinkedHashSet集合
java.util.linkedHashSet集合 extends HashSet集合
LinkedHashSet集合的特点;
底层是;
哈希表+链表;
这里多了一个链表,他的目的就是为了记录元素的存储数据,保证集合中的元素是有序的
代码实现;
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<String>();
set.add("bbb");
set.add("aaa");
set.add("abc");
set.add("bbc");
Iterator<String> it = set.iterator();
while (it.hasNext()) { System.out.println(it.next()); }
}
}
结果:bbb aaa abc bbc
输出的结果,按照输入的数据顺序展示
一个新的类(工具类)
java.utils.Collections : 是一个集合工具类;
常用方法;
-public static boolean addAll(Collection c, T… elements) :往集合中添加一些元素。 ------public static void shuffle(List<?> list) 打乱顺序 :打乱集合顺序。
-public static void sort(List list) :将集合中元素按照默认规则排序。
-public static void sort(List list,Comparator<? super T> ) :将集合中元素按照指定规则排 序。
方法的代码实现(来源于网络);
sort的简单应用(默认的升序排列);
package Day6_22; import java.util.ArrayList; import java.util.Collections; public class demo4 { public static void main(String[] args) { ArrayList<String> array = new ArrayList<>(); array.add("c"); array.add("b"); array.add("a"); array.add("d"); System.out.println(array); Collections.sort(array); System.out.println(array); System.out.println("________________________________"); array.add("1"); array.add("3"); array.add("5"); array.add("2"); System.out.println(array); Collections.sort(array); System.out.println(array); System.out.println("________________________________"); array.add("小明"); array.add("销量"); array.add("重地"); array.add("通话"); System.out.println(array); Collections.sort(array); System.out.println(array); ArrayList<String> list = new ArrayList<>(); list.add("小明"); list.add("小红"); list.add("小蓝"); list.add("小紫"); list.add("小绿"); list.add("小粉"); list.add("小花"); list.add("小亮"); list.add("小波"); list.add("小男孩"); list.add("小二"); Collections.sort(list); System.out.println(list);//[小二, 小亮, 小明, 小波, 小男孩, 小粉, 小紫, 小红, 小绿, 小花, 小蓝] } }
输出结果;
"C:\Program Files\Java\jdk1.8.0_74\bin\java" "-javaagent:D:\ide...............
[c, b, a, d]
[a, b, c, d]
________________________________
[a, b, c, d, 1, 3, 5, 2]
[1, 2, 3, 5, a, b, c, d]
________________________________
[1, 2, 3, 5, a, b, c, d, 小明, 销量, 重地, 通话]
[1, 2, 3, 5, a, b, c, d, 小明, 通话, 重地, 销量]
[小二, 小亮, 小明, 小波, 小男孩, 小粉, 小紫, 小红, 小绿, 小花, 小蓝]
Process finished with exit code 0
注意;
sort(List list)使用的前提;
被排序的集合里边存储的元素,必须实现Comparable接口,重写接口中的compareTo定义的排序规则
图解:
Comparable和Comparator的区别;
Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,并且重写比较的规则compareTo方法
Comparator:相当于找一个第三方裁判,比较两个
上代码;
package Day6_22; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class demo4 { public static void main(String[] args) { ArrayList<Integer> arr = new ArrayList<>(); arr.add(4); arr.add(6); arr.add(2); System.out.println("__________________"); Collections.sort(arr, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { //return o1 - o2;//升序 return o2 - o1;//降序 } }); System.out.println(arr); ArrayList<Person> list = new ArrayList<>(); list.add(new Person("a古力娜扎", 12)); list.add(new Person("f周润发", 50)); list.add(new Person("s大黄蜂", 80)); list.add(new Person("b雷神", 20)); System.out.println("__________________"); System.out.println(list); Collections.sort(list, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } }); System.out.println("__________________"); System.out.println(list); Collections.sort(list, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { int result = o1.getAge()-o2.getAge(); if(result==0){ result = o1.getName().charAt(0) -o2.getName().charAt(0); } return result; } }); System.out.println("__________________"); System.out.println(list); } }
Comparable和Comparator两个接口的区别;
Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法 被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现 此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中 的键或有序集合中的元素,无需指定比较器。
Comparator强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或 有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。
代码分析;
Map集合(重点)
Map集合与Collection中的集合的区别;
Collection中的集合,元素都是孤立存在的(单身狗),向集合中存储的元素都是一个一个的单个元素。
Map中的集合,元素都是成对的出现的,(夫妻)。每个元素都由键与值两个部分组成,通过键可以找到对应的值。
SO,Collection中的集合是单列集合,Map中的集合是双列集合。
注意;
Map集合中不可以包含重复的键,值可以重复:每一个键都只能对应一个唯一得值。
java.util.Map<K,V>集合
Map集合的特点;
(1),Map集合是一个双列集合,一个元素包含两个值(Key,Value)
(2),Map 集合中的元素,Key和Value的数据类型可以相同,也可以不同
(3),Map集合中的元素,Key不允许重复,但是value可以重复
(4),Map集合中的元素,Key和Value是一一对应的
HashMap集合;
java.util.HashMap<K,V>集合implements Map<K,V>接口
(1),HashMap集合的底层是哈希表,特点;查询的速度特别快
(2),JDK1.8之前:数组+单向链表 ,jdk1.8之后 :数组+单向链表/红黑树(链表的长度超出8):提高查询的速度
(3),HashMap集合是一个无序集合
LinkedHashMap集合
java.util.LinkedHashMap<K,V>集合extends HashMap(K,V)
LinkedHashMap集合的特点;
(1),LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)
(2),LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序一致
Map集合中的常用方法;
public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。
public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的 值。
public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
public Set keySet() : 获取Map集合中所有的键,存储到Set集合中。
public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)
(1)put方法(来源网络)
(2)remove方法(来源网络)
(3),get方法(来源网络)
(4)containKey方法(来源网络)
遍历Map集合
Map集合的第一种遍历方式
通过键找值得方法
Map集合中的方法;Set keySet() ;返回的就是此映射中包含的键Set视图
实现的步骤;
(1),使用Map集合中的方法keySet(),把Map集合中所有的Key取出来,存储带一个Set集合中
(2),遍历Set集合,获取Map集合中的每一个key
(3),通过Map集合中的方法get(key),通过key找到value
Map集合的第二种遍历方式;
Set<Map.Entry<K,V>> entrySet()遍历集合
Map.Entry(K,V);在Map接口中有一个内部接口Entry
作用;
当Map集合创建,那么就会在Map集合中创建一个Entry对象,用来记录键与值(键值对对象,键与值得对应关系)
步骤;
(1),使用Map集合中的方法,entrySet(),把Map集合中的多个Entry对象取出来,存储到一个Set集合中
(2),遍历Set集合,获取每一个Entry的值
(3),使用Entry对象中的方法,getKey()和getValue()获取键与值
来源(网络)
在HashMap中存储自定义类型的键值
其中,Map集合保证Key是唯一的
作为Key的元素,必须重写hashCode方法和equals方法,以保证key的唯一;(其用法相同)
代码演示;student学生类;
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; } @Override public 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); } @Override public int hashCode() { return Objects.hash(name, age); } }
测试类
public class HashMapTest {
public static void main(String[] args) {
//1,创建Hashmap集合对象。
Map<Student,String>map = new HashMap<Student,String>();
//2,添加元素。
map.put(newStudent("lisi",28), "上海");
map.put(newStudent("wangwu",22), "北京");
map.put(newStudent("zhaoliu",24), "成都");
map.put(newStudent("zhouqi",25), "广州");
map.put(newStudent("wangwu",22), "南京");
//3,取出元素。键找值方式
Set<Student>keySet = map.keySet();
for(Student key: keySet){ Stringvalue = map.get(key); System.out.println(key.toString()+"....."+value); } } }
HashMap中的子类LinkedHashMap
java.util.LinkedHashMap<K,V> extends HashMap<K,V>
Map 接口的哈希表和链表实现,具有可预知的迭代顺序
底层原理:哈希表+链表(记录元素的顺序)(用法相同)
Hashtable<K,V>集合
HashTable:底层也是一个哈希表,是一个线程安全的集合,单线程集合,速度慢
HashMap:底层是一个哈希表,是一个线程不安全的集合,多线程集合。速度快
HashMap集合(之前学的所有的集合):可以存储null值null键
HashTable集合:不可以存储null值null键
Hashtable和Vector一样,在jdk1.2版本以后就被取代了(HashMap,ArrayList)
Hashtable的子类Properties依然活跃在历史的舞台;
Properties集合是唯一一个和IO流相结合的集合
(来源网络)
在JDK9中集合的优化;
JDK9的新特性;
List接口,Set接口,Map接口:里边增加了一个静态的方法of,可以给集合一次性的添加多个元素
static List of (E…elements)
使用前提;
当集合中存储的元素的个数已经被确定了,不在改变的时候
注意;
(1),of方法只适用于List接口,Set接口,Map接口,不适用于接口的实现类;
(2),of方法的返回值是一个不能改变的集合,集合不能在使用add,put方法,添加元素,会抛出异常
(3),Set接口和Map接口在调用of方法的时候,不能有重复的元素,否则会抛出异常
代码演示;
public static void main(String[] args) {
Set<String> str1=Set.of("a","b","c");
//str1.add("c");这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合
System.out.println(str1);
Map<String,Integer> str2=Map.of("a",1,"b",2);
System.out.println(str2);
List<String> str3=List.of("a","b");
System.out.println(str3);
}
还有一些其他集合,这些只是最为常用得几个。如有不足,请在下方评论区共勉。
注意:转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。