Collection集合类分析
研究问题:
- Collection多种类类型:Set(集)、List(列表)、Map(映射)数据存储??
要点:
- 常用集合类的继承结构如下:
Collection(接口)<–List(接口)<–Vector
Collection(接口)<–List(接口)<–ArrayList
Collection(接口)<–List(接口)<–LinkedList
Collection(接口)<–Set(接口)<–HashSet(实现类)
Collection(接口)<–Set(接口)<–HashSet(实现类) <–LinkedHashSet (实现类)
Collection(接口)<–Set(接口)<–SortedSet(接口)<–TreeSet(实现类)
Map(接口)<–SortedMap(接口)<–TreeMap(实现类)
Map(接口)<–HashMap(实现类) -
Collection
|–List
有序(存储顺序和取出顺序一致),可重复
|–Set
无序(存储顺序和取出顺序不一致,但它有自己的存储顺序),唯一牢记:
ArrayXxx:底层数据结构是数组,查询快,增删慢
LinkedXxx:底层数据结构是链表,查询慢,增删快
HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序 - HashSet内存图解
- TreeSet内存图解
截图展示区:
- Vector数据存储
package com.java.Vector;
import java.util.Enumeration;
import java.util.Vector;
/* 容器类
* Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。
* 但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。
*
* void addElement(E obj) 将指定的组件添加到此向量的末尾,将其大小增加 1。
* E elementAt(int index) 返回指定索引处的组件。
* Enumeration<E> elements() 返回此向量的组件的枚举。
*
* public interface Enumeration<E>实现 Enumeration 接口的对象,
* 它生成一系列元素,一次生成一个。连续调用 nextElement 方法将返回一系列的连续元素。
*/
public class VectorDemo {
public static void main(String[] args) {
Vector v=new Vector<>();
v.addElement("hello");
v.addElement("world");
v.addElement("java");
for(int x=0;x<v.size();x++){
String s=(String) v.elementAt(x);
System.out.println(s);
}
System.out.println("------------");
//使用枚举进行迭代
Enumeration en=v.elements();
while (en.hasMoreElements()) {
String s = (String) en.nextElement();
System.out.println(s);
}
}
}
2.ArrayList数据存储
同Vector一样是一个基于数组上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector好一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。
package com.java.VariableParameter;
/**
* @author FangYang
*
*/
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
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 String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
package com.java.VariableParameter;
import java.util.ArrayList;
/*集合的嵌套遍历
* 多种不同ArrayList的遍历,将不同的ArrayList放置于大的ArrayList集合中
*/
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<ArrayList<Student>> bigArrayList=new ArrayList<ArrayList<Student>>();
//子集合一
ArrayList<Student> firstArrayList=new ArrayList<Student>();
Student s1=new Student("唐僧", 30);
Student s2=new Student("孙悟空", 29);
Student s3=new Student("猪八戒", 28);
Student s4=new Student("沙僧", 27);
Student s5=new Student("白龙马", 26);
firstArrayList.add(s1);
firstArrayList.add(s2);
firstArrayList.add(s3);
firstArrayList.add(s4);
firstArrayList.add(s5);
bigArrayList.add(firstArrayList);
//子集合二
ArrayList<Student> secondArrayList=new ArrayList<Student>();
Student s6=new Student("诸葛亮", 30);
Student s7=new Student("司马懿", 28);
Student s8=new Student("周瑜", 26);
secondArrayList.add(s6);
secondArrayList.add(s7);
secondArrayList.add(s8);
bigArrayList.add(secondArrayList);
//子集合三
ArrayList<Student> thirdArrayList=new ArrayList<Student>();
Student s9=new Student("松江", 40);
Student s10=new Student("吴用", 35);
Student s11=new Student("高俅", 30);
Student s12=new Student("李师师", 22);
thirdArrayList.add(s9);
thirdArrayList.add(s10);
thirdArrayList.add(s11);
thirdArrayList.add(s12);
bigArrayList.add(thirdArrayList);
for(ArrayList<Student> Array:bigArrayList){
for(Student s:Array){
System.out.println(s);
}
}
}
}
3. LinkedList(链表)数据存储
链表不是基于数组的,所以不受数组性能的限制。
它每一个节点(Node)都包含两方面的内容:
1.节点本身的数据(data);
2.下一个节点的信息(nextNode)。
所以当对LinkedList做添加,删除动作的时候就不用像基于数组的ArrayList一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了,这是LinkedList的优势。
package com.java.LinkedList;
import java.util.LinkedList;
/*
List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。
除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove和 insert元素
提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。
void addFirst(E e) 将指定元素插入此列表的开头。
void addLast(E e) 将指定元素添加到此列表的结尾。
E getFirst() 返回此列表的第一个元素。
E getLast() 返回此列表的最后一个元素。
E removeFirst() 移除并返回此列表的第一个元素。
E removeLast() 移除并返回此列表的最后一个元素。
*/
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList link=new LinkedList<>();
link.add("hello");
link.add("world");
link.add("java");
link.addFirst("android");
link.addLast("last");
link.removeFirst();
link.removeLast();
System.out.println("link:"+link);
System.out.println("link.getFirst="+link.getFirst());
System.out.println("link.getLast="+link.getLast());
}
}
4.HashSet数据存储
必须同时重写hashCode()和equals()两个方法,才能使相同属性的对象具有相同哈希值。
package com.java.Set;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<Student> hs=new HashSet<Student>();
Student s1=new Student("林青霞",27);
Student s2=new Student("柳岩", 22);
Student s3=new Student("王祖贤", 30);
Student s4=new Student("林青霞", 20);
Student s5=new Student("范冰冰", 22);
Student s6=new Student("林青霞", 27);
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
hs.add(s5);
hs.add(s6);
for(Student s:hs){
System.out.println(s.toString());
}
}
}
下接自定义Student类
package com.java.Set;
/* 自然排序
1. 实现TreeSet自然排序,必须实现其Comparable接口,并且实现接口compareTo(T o)方法
2. int compareTo(T o)
3. 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
*/
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
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;
}
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
//实现LinkedHashSet排序,必须同时重写hashCode()和equals()两个方法,才能使相同属性的对象具有相同哈希值
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int compareTo(Student o) {
// TODO 自动生成的方法存根
// return 0;//不排序,怎么进来怎么出去
// return 1;//按从小到大排
// return -1;//按从大到小排
int num=this.age-o.age;//主要条件
//次要条件
int num2=num==0? this.name.compareTo(o.name):num;
return num2;
}
}
5. TreeSet数据存储
两种排序方式:A.自然排序。B.比较器排序
package com.java.Set;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
//按从高到低排序学生总成绩
public class TreeSetDemo4 {
public static void main(String[] args) {
TreeSet<Pupil> ts=new TreeSet<Pupil>(new Comparator<Pupil>() {
//比较器排序
//使用匿名内部类实现接口的实现类对象
public int compare(Pupil o1, Pupil o2) {
// TODO 自动生成的方法存根
int num=o2.getSum()-o1.getSum();
int num2=num==0?o1.getChineseScore()-o1.getChineseScore():num;
int num3=num2==0?o1.getMathScore()-o2.getMathScore():num2;
int num4=num3==0?o1.getEnglishScore()-o2.getEnglishScore():num3;
int num5=num4==0?o1.getName().compareTo(o2.getName()):num4;
return num5;
}
});
Scanner sc=new Scanner(System.in);
for(int x=1;x<=5;x++){
System.out.println("输入第"+x+"个学生的姓名:");
String name=sc.nextLine();
System.out.println("输入第"+x+"个学生的语文成绩:");
int ChineseScore=sc.nextInt();
System.out.println("输入第"+x+"个学生的数学成绩:");
int MathScore=sc.nextInt();
System.out.println("输入第"+x+"个学生的英语成绩:");
int EnglishScore=sc.nextInt();
sc.nextLine();
Pupil p=new Pupil(name, ChineseScore, MathScore, EnglishScore);
/*p.setName(name);
p.setChineseScore(ChineseScore);
p.setMathScore(MathScore);
p.setEnglishScore(EnglishScore);*/
ts.add(p);
}
System.out.println("学生信息从高到底排序:");
System.out.println("姓名\t语文\t数学\t英语");
for(Pupil p:ts){
System.out.println(p.getName()+"\t"+p.getChineseScore()+"\t"+p.getMathScore()+"\t"+p.getEnglishScore());
}
}
}
6. HashMap数据存储
package com.java.Map;
import java.util.HashMap;
import java.util.Map;
/* public interface Map<K,V>
* 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
*
* Map集合概述
* 1.添加功能
* V put(K key, V value)将指定的值与此映射中的指定键关联(可选操作)。
* 2.删除功能
* void clear()从此映射中移除所有映射关系(可选操作)。此调用返回后,该映射将为空。
* V remove(Object key)如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
* 3.判断功能
* boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true。
* boolean containsValue(Object value)如果此映射将一个或多个键映射到指定值,则返回 true。
* 4.获取功能
* Set<Map.Entry<K,V>> entrySet()返回此映射中包含的映射关系的 Set视图。
* V get(Object key)返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
* Set<K> keySet()返回此映射中包含的键的 Set 视图。
* Collection<V> values()返回此映射中包含的值的 Collection 视图。
* 5.长度功能
* int size()返回此映射中的键-值映射关系数。
*/
/*public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
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;
}
*/
public class MapDemo {
public static void main(String[] args) {
Map<String, String> map=new HashMap<String, String>();
// System.out.println("put:"+map.put("1407010401", "方杨"));
map.put("1407010402", "周杰伦");
map.put("1407010403", "张杰");
map.put("1407010404", "杨幂");
map.put("1407010405", "金轮法王");
// map.clear();
//remove()只能删除键
/*System.out.println("remove:"+map.remove("1407010403"));
System.out.println("remove:"+map.remove("杨幂"));
System.out.println("remove:"+map.remove("赵钱孙李"));*/
/*System.out.println("containsKey:"+map.containsKey("1407010403"));
System.out.println("containsKey:"+map.containsKey("1407010401"));*/
System.out.println("isEmpty:"+map.isEmpty());
System.out.println("map:"+map);
System.out.println("size:"+map.size());
}
}
7.HashMap嵌套型数据存储
package com.java.HashMap;
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<String, HashMap<String, Integer>> hm=new HashMap<String, HashMap<String,Integer>>();
HashMap<String, Integer> jcMap=new HashMap<String, Integer>();
jcMap.put("小陈", 20);
jcMap.put("小高", 22);
hm.put("jc", jcMap);
HashMap<String, Integer> jyMap=new HashMap<String, Integer>();
jyMap.put("小李", 21);
jyMap.put("小曹", 23);
hm.put("jy", jyMap);
Set<String> hmSet=hm.keySet();
for(String hmKey:hmSet){
System.out.println(hmKey);
HashMap<String, Integer> hmValue=hm.get(hmKey);
Set<String> hmValueSet=hmValue.keySet();
for(String s:hmValueSet){
Integer itValue=hmValue.get(s);
System.out.println("\t"+s+"---"+itValue);
}
}
}
}
8.HashMap-ArrayList数据存储
package com.java.HashMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
/*
* HashMap集合元素是ArrayList,有3个
* 每一个ArrayList集合的值是字符串
*/
class HashMapIncludeArrayListDemo {
public static void main(String[] args) {
HashMap<String, ArrayList<String>> hm=new HashMap<String, ArrayList<String>>();
ArrayList<String> array1=new ArrayList<String>();
array1.add("吕布");
array1.add("周瑜");
hm.put("三国演义", array1);
ArrayList<String> array2=new ArrayList<>();
array2.add("令狐冲");
array2.add("林平之");
hm.put("笑傲江湖", array2);
ArrayList<String> array3=new ArrayList<String>();
array3.add("郭靖");
array3.add("杨过");
hm.put("神雕侠侣", array3);
Set<String> set=hm.keySet();
for(String key:set){
System.out.println(key);
ArrayList<String> arrayValue=hm.get(key);
for(String key2:arrayValue){
System.out.println("\t"+key2);
}
}
}
}
9.ArrayList-HashMap数据存储
package com.java.ArrayList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class ArrayListIncludeHashMapDemo {
public static void main(String[] args) {
ArrayList<HashMap<String, String>> array=new ArrayList<HashMap<String,String>>();
HashMap<String, String> hm1=new HashMap<String, String>();
hm1.put("周瑜", "小乔");
hm1.put("吕布", "貂蝉");
array.add(hm1);
HashMap<String, String> hm2=new HashMap<String, String>();
hm2.put("郭靖", "黄蓉");
hm2.put("杨过", "小龙女");
array.add(hm2);
HashMap<String, String> hm3=new HashMap<String, String>();
hm3.put("令狐冲", "任盈盈");
hm3.put("林平之", "岳灵珊");
array.add(hm3);
for (HashMap<String, String> hm : array) {
Set<String> set=hm.keySet();
for (String key : set) {
String value=hm.get(key);
System.out.println(key+"---"+value);
}
}
}
}
10.HashMap-(HashMap-ArrayList)数据存储
package com.java.HashMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class HashMapIncludeHashMap {
public static void main(String[] args) {
HashMap<String, HashMap<String, ArrayList<Student>>> hs=new HashMap<String, HashMap<String,ArrayList<Student>>>();
//Map一:北京校区
HashMap<String, ArrayList<Student>> hm1=new HashMap<String, ArrayList<Student>>();
hs.put("北京校区", hm1);
ArrayList<Student> array1=new ArrayList<Student>();
hm1.put("基础班", array1);
Student s1=new Student("林青霞",27);
Student s2=new Student("风清扬",30);
array1.add(s1);
array1.add(s2);
ArrayList<Student> array2=new ArrayList<Student>();
hm1.put("就业班", array2);
Student s3=new Student("赵雅芝",28);
Student s4=new Student("武鑫鑫",29);
array2.add(s3);
array2.add(s4);
//Map二:上海校区
HashMap<String, ArrayList<Student>> hm2=new HashMap<String, ArrayList<Student>>();
hs.put("上海校区", hm2);
ArrayList<Student> array3=new ArrayList<Student>();
hm2.put("基础班", array3);
Student s5=new Student("郭美美",20);
Student s6=new Student("犀利哥",22);
array3.add(s5);
array3.add(s6);
ArrayList<Student> array4=new ArrayList<Student>();
hm1.put("就业班", array4);
Student s7=new Student("罗玉凤",21);
Student s8=new Student("马征",23);
array4.add(s7);
array4.add(s8);
//Map三:广州校区
HashMap<String, ArrayList<Student>> hm3=new HashMap<String, ArrayList<Student>>();
hs.put("上海校区", hm3);
ArrayList<Student> array5=new ArrayList<Student>();
hm3.put("基础班", array5);
Student s9=new Student("王力宏",30);
Student s10=new Student("李晶磊",32);
array5.add(s9);
array5.add(s10);
ArrayList<Student> array6=new ArrayList<Student>();
hm3.put("就业班", array6);
Student s11=new Student("郎朗",31);
Student s12=new Student("柳岩",33);
array6.add(s11);
array6.add(s12);
//Map四:西安校区
HashMap<String, ArrayList<Student>> hm4=new HashMap<String, ArrayList<Student>>();
hs.put("西安校区", hm4);
ArrayList<Student> array7=new ArrayList<Student>();
hm4.put("基础班", array7);
Student s13=new Student("范冰冰",30);
Student s14=new Student("刘意",32);
array7.add(s13);
array7.add(s14);
ArrayList<Student> array8=new ArrayList<Student>();
hm4.put("就业班", array8);
Student s15=new Student("李冰冰",28);
Student s16=new Student("张志豪",29);
array8.add(s15);
array8.add(s16);
Set<String> set=hs.keySet();
for(String hsKey:set){
System.out.println(hsKey);
HashMap<String, ArrayList<Student>> hsValue=hs.get(hsKey);
Set<String> hsValueSet=hsValue.keySet();
for(String hsValueKey:hsValueSet){
System.out.println("\t"+hsValueKey);
ArrayList<Student> arraylist=hsValue.get(hsValueKey);
for(Student s:arraylist){
System.out.println("\t\t"+s.getName()+"---"+s.getAge());
}
}
}
}
}
11.TreeMap数据存储
package com.java.TreeMap;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapDemo2 {
public static void main(String[] args) {
TreeMap<Student, String> tm=new TreeMap<Student, String>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// TODO 自动生成的方法存根
int num=o1.getAge()-o2.getAge();
int num2=num==0?o1.getName().compareTo(o2.getName()):num;
return num2;
}
});
Student s1=new Student("潘安",30);
Student s2=new Student("柳下惠",35);
Student s3=new Student("唐伯虎",33);
Student s4=new Student("燕青",32);
Student s5=new Student("唐伯虎",33);
tm.put(s1, "宋");
tm.put(s2, "元");
tm.put(s3, "明");
tm.put(s4, "清");
tm.put(s5, "汉");
Set<Student> set=tm.keySet();
for (Student s:set) {
String value=tm.get(s);
System.out.println(s.getName()+"---"+s.getAge()+"---"+value);
}
}
}
上一篇: 硬件设计6---什么是滞回电路
下一篇: TreeMap源码解析