java基础总结21-java集合
来源:互联网 发布:杭州淘宝网汽车拍卖 编辑:程序博客网 时间:2024/06/18 09:57
1 集合的由来及与数组的区别
集合类的由来:面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类。
数组和集合类同的区别:
数组可以存储同一种类型的基本数据也可以存储同一种类型的对象,但长度是固定的
集合只可以存储不同类型的对象,长度是可变的
集合类的特点:集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
2 集合的继承体系图解
集合容器因为内部的数据结构不同,有多种具体容器,根据共性内容不断的向上抽取,就形成了集合框架。
框架的顶层Collection接口
3 Collection集合
Collection 层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接实现:它提供更具体的子接口(如 Set 和 List)实现。此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。
3.1 成员方法
boolean add(E e):确保此 collection 包含指定的元素(可选操作)。
boolean remove(Object o):从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
void clear():移除此 collection 中的所有元素(可选操作)。
boolean contains(Object o):如果此 collection 包含指定的元素,则返回 true。
boolean isEmpty():如果此 collection 不包含元素,则返回 true。
int size():返回此 collection 中的元素数。
例:
// 创建集合对象// Collection c = new Collection(); //错误,因为接口不能实例化Collection c = new ArrayList();c.add("hello");c.add("world");c.add("java");// c.clear();//移除所有元素// System.out.println("remove:" + c.remove("hello"));//移除一个元素// System.out.println("remove:" + c.remove("javaee"));// 判断集合中是否包含指定的元素 System.out.println("contains:"+c.contains("hello"));//contains:true System.out.println("contains:"+c.contains("android"));//contains:false //判断集合是否为空 System.out.println("isEmpty:"+c.isEmpty());//isEmpty:false//元素的个数System.out.println("size:"+c.size());//size:3System.out.println("c:" + c);//c:[hello, world, java]
高级功能成员方法:1. boolean addAll(Collection<? extends E> c):将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。2. boolean removeAll(Collection<?> c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。3. boolean containsAll(Collection<?> c):如果此 collection 包含指定 collection 中的所有元素,则返回 true。4. boolean retainAll(Collection<?> c):仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。换句话说,移除此 collection 中未包含在指定 collection 中的所有元素。
例:
c1.addAll(c2);//将c2集合中的所有元素添加到c1集合中,c1变c2不变c1.removeAll(c2);//将c1集合中与c2集合相同的所有元素删除,只要有一个相同的就返回truec1.containsAll(c2);//判断c1集合中的元素是否包含c2中的全部元素,全部包含则返回truec1.retainAll(c2);//将c1集合中与c2集合相同的元素保留,删除其他元素,返回值表示c1集合是否发生变化,发生变化返回true,没有变化返回false
3.2 集合的遍历
集合的遍历之集合转数组遍历
Object[] toArray():返回包含此 collection 中所有元素的数组。
例:
public class Practice { public static void main(String[] args) { // 创建集合 Collection c = new ArrayList(); c.add("hello"); c.add("world"); c.add("java"); Object[] objs = c.toArray(); for (int i = 0; i < objs.length; i++) { //向下转为String类型 String s = (String)objs[i]; System.out.println(s+":"+s.length()); } }}
运行结果:
hello:5world:5java:4
集合的遍历之迭代器遍历
Iterator iterator():返回在此 collection 的元素上进行迭代的迭代器。
例:
// 创建集合Collection c = new ArrayList();//创建元素并添加到集合c.add("hello");c.add("world");c.add("java");//获取迭代器,实际返回的是子类对象,多态Iterator it = c.iterator();while(it.hasNext()){ System.out.println(it.next());}
迭代器使用的问题探讨
- 使用迭代器获取元素的两种方式:
方式1:
Iterator it = c.iterator();while(it.hasNext()){ Student s = (Student)it.next(); System.out.println(s.getName()+":"+s.getAge());}
方式2:
for(Iterator it = c.iterator();it.hasNext();){ Student s = (Student)it.next(); System.out.println(s.getName()+":"+s.getAge());}
使用方式2的好处:it在for循环结束后就变成垃圾,效率较高
- 不要多次使用it.next()方法
例:
Iterator it = c.iterator();while(it.hasNext()){ System.out.println(((Student)it.next()).getName()); System.out.println(((Student)it.next()).getAge());}
上面的代码表示获取的是第1个学生的姓名,第2个学生的年龄,以此类推,如果集合中的元素是奇数个,则会报NoSuchElementException错误
3.3 集合的使用步骤图解
集合的使用步骤:
创建集合对象
创建元素对象
将元素添加到集合
遍历集合
4.1 通过集合对象获取迭代器对象
4.2 通过迭代器对象的hasNext()方法判断是否有元素
4.3 通过迭代器对象的Next()方法获取元素并移动到下一个位置
3.4 Collection存储学生对象并遍历
import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;public class Practice { public static void main(String[] args) { // 创建集合 Collection c = new ArrayList(); //创建学生对象并添加到集合 c.add(new Student("小明",23)); c.add(new Student("小红",32)); c.add(new Student("小强",14)); c.add(new Student("旺财",8)); c.add(new Student("张三",16)); Iterator it = c.iterator(); while(it.hasNext()) { Student s = (Student)it.next(); System.out.println(s.getName()+":"+s.getAge()); } }}
4 List集合
List接口概述:有序的(存取顺序一致)collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
特点:与 set 不同,列表通常允许重复的元素。
4.1 List集合的特有功能
1. void add(int index,E element):在列表的指定位置插入指定元素(可选操作)。2. E remove(int index):移除列表中指定位置的元素(可选操作)。3. E get(int index):返回列表中指定位置的元素。4. E set(int index, E element):用指定元素替换列表中指定位置的元素(可选操作)。例:list.add(2,"javaee");//在2的位置插入javaee,改变集合长度list.get(2)//返回集合中2位置上的元素,不改变集合长度list.remove(1)//删除集合中1位置上的元素,返回被删除的元素,改变集合长度list.set(2, "javaee")//将集合中2位置上的元素替换为javaee,返回被替换的元素,不改变集合长度
4.2 List存储学生对象并遍历
public class Practice { public static void main(String[] args) { // 创建集合 List list = new ArrayList(); //创建学生对象并添加到集合 list.add(new Student("小明",23)); list.add(new Student("小红",32)); list.add(new Student("小强",14)); list.add(new Student("旺财",8)); list.add(new Student("张三",16)); Iterator it = list.iterator(); while(it.hasNext()) { Student s = (Student)it.next(); System.out.println(s.getName()+":"+s.getAge()); } }}
4.3 List的三个子类的特点
ArrayList:底层数据结构是数组,查询快,增删慢,是不同步的,线程不安全,效率高
Vector:底层数据结构是数组,查询快,增删慢,是同步的,线程安全,效率低
LinkedList:底层数据结构是链表,查询慢,增删快,是不同步的,线程不安全,效率高
5 Set集合
Set接口概述:一个不包含重复元素的 collection
特点:
无序(存入与取出的顺序不一致)
唯一(存入集合的元素唯一)
5.1 HashSet
HashSet存储字符串并遍历
HashSet类概述:不保证 set 的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
例:
public class Practice { public static void main(String[] args) { HashSet<String> hs = new HashSet<String>(); hs.add("hello"); hs.add("world"); hs.add("world"); hs.add("java"); for (String s : hs) { System.out.println(s); } }}
运行结果:
hellojavaworld
HashSet保证元素唯一性的源码解析
interface Collection{...}interface Set extends Collection {...}class HashSet implements Set { private static final Object PRESENT = new Object(); private transient HashMap<E,Object> map; public HashSet() { map = new HashMap<>(); } public boolean add(E e) { //e=hello,world return map.put(e, PRESENT)==null; }}class HashMap implements Map { public V put(K key, V value) { //key=e=hello,world //看哈希表是否为空,如果空,就开辟空间 if (table == EMPTY_TABLE) { inflateTable(threshold); } //判断对象是否为null if (key == null) return putForNullKey(value); int hash = hash(key); //和对象的hashCode()方法相关 //在哈希表中查找hash值 int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { //这次的e其实是第一次的world Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; //走这里其实是没有添加元素 } } modCount++; addEntry(hash, key, value, i); //把元素添加 return null; } transient int hashSeed = 0; final int hash(Object k) { //k=key=e=hello, int h = hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); //这里调用的是对象的hashCode()方法 // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }}
通过查看add方法的源码,知道这个方法底层依赖两个方法:hashCode()和equals()。
判断元素唯一性的方式:通过对象的hashCode和equals方法来完成元素唯一性
- 如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
- 如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
- 如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。
如果类没有重写这两个方法,默认使用的Object()。一般来说不会相同。
5.2 TreeSet
TreeSet类概述:使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
真正的比较是依赖于元素的compareTo()方法,而这个方法是定义在 Comparable里面的。
所以,要想重写该方法,就必须是先实现 Comparable接口。这个接口表示的就是自然排序。
TreeSet对元素排序的总结
唯一性:根据比较的返回的是否是0来决定
排序:
自然排序,一个类的元素想要进行自然排序就必须实现自然排序接口Comparable(元素具备比较性)
比较器排序,让集合的构造方法接收一个比较器接口的子类对象Comparator(集合具备比较性)
6 Map集合
6.1 Map集合概述和特点
Map接口概述:将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值
Map接口和Collection接口的不同
1.Map是双列的,Collection是单列的
2.Map的键唯一,Collection的子体系Set是唯一的
3.Map集合的数据结构值针对键有效,跟值无关,Collection集合的数据结构是针对元素有效
6.2 Map集合的功能概述
成员方法:1.V put(K key,V value):将指定的值与此映射中的指定键关联(可选操作)。2.V remove(Object key):如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。3.void clear():从此映射中移除所有映射关系(可选操作)。4.boolean containsKey(Object key):如果此映射包含指定键的映射关系,则返回 true。5.boolean containsValue(Object value):如果此映射将一个或多个键映射到指定值,则返回 true。6.boolean isEmpty():如果此映射未包含键-值映射关系,则返回 true。7.int size():返回此映射中的键-值映射关系数。8.V get(Object key)返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。9.Set<K> keySet()返回此映射中包含的键的 Set 视图。10.Collection<V> values()返回此映射中包含的值的 Collection 视图。11.Set<Map.Entry<K,V>> entrySet()返回此映射中包含的映射关系的 Set 视图。
6.3 Map集合的基本功能测试
map.put(“001”, “旺财”); :第一次存储直接存储元素,返回null
map.put(“001”, “小强”); :不是第一次存储,用新值将以前的值替换掉,返回以前的值
map.remove(“001”); :根据键删除键值对元素,并返回键所对应的值,没有则返回空
6.4 Map集合的获取功能测试
Map<String, String> map = new HashMap<String, String>();map.put("001", "小明");map.put("002", "旺财");map.put("003", "小强");//根据键获取值System.out.println(map.get("002"));//旺财,没有该键返回nullSystem.out.println("-----");//获取集合中所有键的集合Set<String> set = map.keySet();for(String key : set){ System.out.println(key);}System.out.println("-----");//获取集合中所有值的集合Collection<String> coll = map.values();for(String value : coll){ System.out.println(value);}
6.5 Map集合的遍历之键找值
根据键找值:
获取所有键的集合,遍历键的集合,获取到每一个键,根据键找值
Map<String, String> map = new HashMap<String, String>();map.put("001", "小明");map.put("002", "旺财");map.put("003", "小强");//获取所有的键Set<String> set = map.keySet();for(String key : set){ //根据键找值 String value = map.get(key); System.out.println(key+":"+value);}
6.6 Map集合的遍历之键值对对象找键和值
根据键值对对象找键和值:
获取所有键值对对象的集合,遍历键值对对象的集合,获取到每一个键值对对象,根据键值对对象找键和值
Map<String, String> map = new HashMap<String, String>();map.put("001", "小明");map.put("002", "旺财");map.put("003", "小强");//获取所有键值对对象的集合Set<Map.Entry<String, String>> set = map.entrySet();//遍历键值对对象的集合,获取每一个键值对对象for(Map.Entry<String, String> me : set){ //根据键值对对象获取键和值 String key = me.getKey(); String value = me.getValue(); System.out.println(key+":"+value);}
7 集合总结
7.1 判断元素唯一性
HashSet、HashMap、Hashtable判断元素唯一性的方式:
通过对象的hashCode和equals方法来完成元素唯一性
如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。
最终:自动生成hashCode()和equals()即可
TreeSet、TreeMap判断元素唯一性的方式:根据比较的返回的是否是0来决定
7.2 TreeSet排序
1.自然排序,一个类的元素想要进行自然排序就必须实现自然排序接口Comparable(元素具备比较性)
2.比较器排序,让集合的构造方法接收一个比较器接口的子类对象Comparator(集合具备比较性)
7.3 如何选择使用哪种集合
7.4 集合常见功能和遍历方式
集合的常见方法及遍历方式
Collection:add()、remove()、contains()、iterator()、size()
遍历:增强for、迭代器
Collection子类List:get()
遍历:普通for
Collection子类Set
Map:put()、remove()、containskey()、containsValue()、keySet()、get()、value()、entrySet()、size()
遍历:根据键找值、根据键值对对象分别找键和值
8 集合面试题
8.1 Hashtable和HashMap的区别
Hashtable:线程安全,效率低。不允许null键和null值
HashMap:线程不安全,效率高。允许null键和null值
8.2 List,Set,Map等接口是否都继承子Map接口?
List,Set不是继承自Map接口,它们继承自Collection接口
Map接口本身就是一个顶层接口
- java集合基础总结
- java集合基础总结
- java集合基础总结
- Java集合基础总结
- java 基础 集合 总结
- Java基础集合总结
- java基础总结21-java集合
- java基础 Java集合总结
- java集合基础知识点总结
- Java集合框架基础总结
- Java基础总结之集合
- java基础之集合总结
- java基础[9]集合总结
- java基础-集合类总结
- Java基础总结8---Java集合
- Java基础(三):Java集合总结
- java基础——集合总结
- 黑马程序员java基础篇----集合总结
- MyEclipse中创建maven项目时: Could not resolve archetype
- java中static的使用
- Docker Sample applications 文档 ——Quickstart: Compose and Django
- URL +io 进行使用 -后台使用现有接口进行调用。
- CLR via C# 第6章
- java基础总结21-java集合
- Nginx反向代理,负载均衡,redis session共享,keepalived高可用
- 从RGB色转为灰度色算法
- 数据结构:栈的顺序存储(三)
- 模拟退火算法
- LightOJ
- Java 8 函数式接口、lambda表达式、方法以及构造器引用
- Loi Online Judge 42. 「Loi57 test 2017.4.22」字符串
- 绘制智能变换圆角及椭圆