java:集合总结
集合的特点:只用于存储对象,集合长度可变,可以存储不同类型的对象
Java中常用的两个主要集合体系:
Collection接口
|----List接口
|——Vector类
|——ArrayList类
|——LinkedList类
|——Set接口
|——HashSet类
|——TreeSet类
Map接口
|——HashMap类
|——TreeMap类
|——HashTable类
|——Properties类
下面简要介绍各类的主要特点和使用方法。
(一)Collection体系
(1)List集合:有序(元素的存入和取出顺序一致),可以重复
(a)Vector类特点:内部是数组数据结构,是同步的。枚举是Vector特有的取出
(b)ArrayList类特点:内部是数组数据结构,不同步。替代的Vector。
(c)LinkedList类特点:内部是链表数据结构,不同步,删除、添加元素速度很快。
以ArrayListt集合为例,说明该集合的一些操作:
//导包
import java.util.*;
//学生类,作为集合的元素
class Student
{
private String name;
private int age;
//get方法
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//构造函数
public Student(String name, int age)
{
this.name = name;
this.age = age;
}
//调用集合的contains方法时,需要覆写元素对象的equals方法
public boolean equals(Object obj)
{
Student s = (Student)obj;
if(this.name == s.name && this.age == s.age)
return true;
else
return false;
}
//toString方法
public String toString()
{
return name +":"+age;
}
}
class TestList
{
public static void main(String[] args)
{
//1.创建ArrayList集合
ArrayList<Student> al = new ArrayList<Student>();
//2.向集合中添加元素
al.add(new Student("lisi01", 12));
al.add(new Student("lisi11", 15));
al.add(new Student("lisi02", 22));
al.add(new Student("lisi01", 12));
//3.打印集合
System.out.println(al);
//结果是:[lisi01:12, lisi11:15, lisi02:22, lisi01:12]
//4.获取集合的长度
System.out.println(al.size());//结果是:4
//4.删除元素
//al.remove("lisi00");
//System.out.println(al);
//结果是:[lisi30, lisi01, lisi20, lisi00]
//5.清空集合
//al.clear();
//System.out.println(al); //结果是:[]
//6.判断集合中是否包含元素
Student stu = new Student("lisi02", 22);
System.out.println(al.contains(stu)); //结果是:true
//实现contains方法,必须覆写元素equals方法
//7.判断结合是否为空
System.out.println(al.isEmpty()); //结果是:false
//8.取出list集合中的元素,运用迭代器Iterator
Iterator<Student> it = al.iterator();
while(it.hasNext())
{
Student s = it.next();
System.out.print(s +" ");
}
System.out.println();
//打印结果是:lisi01:12 lisi11:15 lisi02:22 lisi01:12
//9.用高级for循环取出List中的元素
for(Student s : al)
{
System.out.print(s +" ");
}
System.out.println();
//打印结果是:lisi01:12 lisi11:15 lisi02:22 lisi01:12
//10.用Lis集合特有的迭代器ListIterator取出元素,可以在遍历中增加元素
ListIterator<Student> lit = al.listIterator();
while(lit.hasNext())
{
Student s = lit.next();
if(s.equals((Object)new Student("lisi11", 15)))
lit.add(new Student("lisi12", 25));
}
System.out.println(al);
//结果是:[lisi01:12, lisi11:15, lisi12:25, lisi02:22, lisi01:12]
//11.通过脚标获取元素
for(int i = 0; i < al.size(); i++)
{
System.out.print(al.get(i) +" ");
}
System.out.println();
//结果是:lisi01:12 lisi11:15 lisi12:25 lisi02:22 lisi01:12
//12.集合中的元素进行排序,按指定比较器排序
Collections.sort(al, new myCpmpare());
System.out.println(al);
//结果是:[lisi01:12, lisi01:12, lisi02:22, lisi11:15, lisi12:25]
ArrayList<Student> a = new ArrayList<Student>();
a.add(new Student("lisi01", 12));
a.add(new Student("lisi11", 12));
a.add(new Student("lisi02", 22));
System.out.println(a);
//结果是:[lisi01:12, lisi11:12, lisi02:22]
//13.取集合a1,a交集,al中保留和a相同的元素
al.retainAll(a);
System.out.println(al);
//结果是:[lisi01:12, lisi01:12, lisi02:22]
//14.取差集,al中保留和a不同的元素
al.removeAll(a);
System.out.println(al);
//结果是:[]
}
}
//自定义比较器
class myCpmpare implements Comparator<Student>
{
//覆写compare方法
public int compare(Student s1, Student s2)
{
//先按姓名排序
int flag = s1.getName().compareTo(s2.getName());
if(flag > 0)
return 1;
else if(flag < 0)
return -1;
else
return s1.getAge() - s2.getAge();
}
}
LinkedList集合的一些特有方法:
//导包
import java.util.*;
class TestLinkedList
{
public static void main(String[] args)
{
//创建LinkList的容器
LinkedList<String> ld = new LinkedList<String>();
//向容器中添加元素
ld.add("zhangsan00");
ld.add("zhangsan30");
ld.add("zhangsan02");
ld.add("zhangsan01");
//打印容器
System.out.println(ld); //结果是:[zhuangsan00, zhuangsan30, zhuangsan02, zhuangsan01]
//删除头元素
ld.removeFirst();
System.out.println(ld); //结果是:[zhuangsan30, zhuangsan02, zhuangsan01]
//删除尾元素
ld.removeLast();
System.out.println(ld); //结果是:[zhuangsan30, zhuangsan02]
//向头添加元素
ld.addFirst("zhangsan10");
System.out.println(ld); //结果是:[zhangsan10, zhangsan30, zhangsan02]
//向尾添加元素
ld.addLast("zhangsan08");
System.out.println(ld); //结果是:[zhangsan10, zhangsan30, zhangsan02, zhangsan08]
//在指定位置插入元素
ld.add(3,"zhangsan03");
System.out.println(ld); //结果是:[zhangsan10, zhangsan30, zhangsan02, zhangsan03, zhangsan08]
}
}
(2)Set集合:无序(元素的存入和取出顺序不一致),不可重复
(a)HashSet类特点:底层是哈希表数据结构,不同步。通过元素覆写hashCode()和equals()方法,而保证元素的唯一性。
(b)TreeSet类特点:底层数据结构是二叉树,不同步。元素必须实现comparable接口并覆写compareTo()方法或把实现comparator接口并覆写compare()方法的比较器传入TreeSet集合,才能把元素添加到集合,同时保证元素的唯一性;如果两者都存在,以集合的比较器为主
HashSet的例子:
//导包
import java.util.*;
//学生类,作为集合的元素
class Student
{
private String name;
private int age;
//构造函数
public Student(String name, int age)
{
this.name = name;
this.age = age;
}
public int hashCode()
{
return name.hashCode() + age;
}
public boolean equals(Object obj)
{
Student s = (Student)obj;
if(this.name == s.name && this.age == s.age)
return true;
else
return false;
}
//toString方法
public String toString()
{
return name +":"+age;
}
}
class TestHashSet
{
public static void main(String[] args)
{
//创建集合
HashSet<Student> hs = new HashSet<Student>();
//向集合中添加元素
hs.add(new Student("lisi01", 12));
hs.add(new Student("lisi11", 15));
hs.add(new Student("lisi02", 22));
hs.add(new Student("lisi01", 12));
//打印集合
System.out.println(hs);
//覆写元素的HashCode方法和equals方法前,结果是:[lisi01:12, lisi11:15, lisi02:22, lisi01:12]
/*元素出现了重复。HashSet中的对象以哈希表的结构存储,HashCode表示对象的地址值。
不同的对象,HashCode就不一样,所以上面内容相同的两个对象都存储在了集合中。
为了保证集合中元素的唯一性,必须覆写元素的HashCode方法和equals方法
覆写元素的HashCode方法和equals方法后,结果是:[lisi02:22, lisi01:12, lisi11:15]
*/
//用迭代器取出集合中的元素
Iterator<Student> it = hs.iterator();
while(it.hasNext())
{
System.out.print(it.next() +" ");
}
System.out.println();
//打印结果是:lisi02:22 lisi01:12 lisi11:15
//用高级for循环取出集合中的元素
for(Student stu : hs)
{
System.out.print(stu +" ");
}
//打印结果是:lisi02:22 lisi01:12 lisi11:15
}
}
TreeSet的例子:
import java.util.*;
//学生类,作为集合的元素,实现Comparable接口的compareTo方法,使其具有比较性
class Student implements Comparable
{
private String name;
private int age;
//构造函数
public Student(String name, int age)
{
this.name = name;
this.age = age;
}
//get方法
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public int compareTo(Object obj)
{
Student s = (Student)obj;
int com = this.name.compareTo(s.name);
if(com > 0)
return 1;
else if(com < 0)
return -1;
else
return this.age - s.age;
}
//toString方法
public String toString()
{
return name +":"+age;
}
}
class TestTreeSet
{
public static void main(String[] args)
{
TreeSet<Student> ts = new TreeSet<Student>(new MyCompare());
//向集合中添加元素
ts.add(new Student("lisi11", 15));
ts.add(new Student("lisi02", 22));
ts.add(new Student("lisi01", 12));
ts.add(new Student("lisi01", 12));
//打印集合
System.out.println(ts);
//结果是:[lisi01:12, lisi11:15, lisi02:22]
}
}
//自定义比较器
class MyCompare implements Comparator<Student>
{
public int compare(Student s1, Student s2)
{
int com = s1.getAge() - (s2.getAge());
if(com > 0)
return 1;
else if(com < 0)
return -1;
else
return s1.getName().compareTo(s2.getName());
}
}
(二)Map体系,以键值对的形式存储,并保证键的唯一性
(1)HashMap集合:底层是哈希表数据结构,允许null键null值,不同步。和HashSet很像,通过覆写键值类的hashCode()和equals()方法,而保证键值的唯一性。
(2)TreeMap集合:底层是二叉树数据结构,线程同步。和TreeSet很像,键值对象必须实现comparable接口并覆写compareTo()方法或把实现comparator接口并覆写compare()方法的比较器传入TreeMap集合,才能把元素添加到集合,同时保证元素的唯一性,并对键值进行排序。
(3)Hashtable集合:底层是哈希表数据结构,不可以存入null键和null值,线程同步。
下面以TreeMap为例,说明Map集合的主要操作:
</pre><pre name="code" class="java">//导包
import java.util.*;
//学生类,作为集合的元素
class Student implements Comparable
{
private String name;
private int age;
//构造函数
public Student(String name, int age)
{
this.name = name;
this.age = age;
}
//get方法
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//覆写compareTo方法
public int compareTo(Object obj)
{
Student s = (Student)obj;
int com = this.name.compareTo(s.name);
if(com > 0)
return 1;
else if(com < 0)
return -1;
else
return this.age - s.age;
}
//toString方法
public String toString()
{
return name +":"+age;
}
}
class TestTreeMap
{
public static void main(String[] args)
{
//创建TreeMap集合
TreeMap<Student, Integer> tm = new TreeMap<Student, Integer>(new MyCompare()); //
//向集合中添加元素
//向集合中添加元素
tm.put(new Student("zhangsan11", 18), new Integer(1));
tm.put(new Student("zhangsan03", 38), new Integer(3));
tm.put(new Student("zhangsan32", 28), new Integer(2));
tm.put(new Student("zhangsan03", 38), new Integer(3));
tm.put(new Student("zhangsan23", 38), new Integer(2));
System.out.println(tm);
//打印结果:{zhangsan11:18=1, zhangsan32:28=2, zhangsan03:38=3, zhangsan23:38=2}
/*当键值对象实现了comparable接口并覆写compareTo()方法时具有了比较性,同时集合又自定义了比较器,
键值的排序将以集合的比较器为主*/
//取出Map集合中的元素
//1.根据Mpa集合keySet()方法把键值对象保存在set集合中,再根据集合的get方法,取出对应键的值
Set<Student> keys = tm.keySet();
Iterator<Student> it = keys.iterator();
while(it.hasNext())
{
Student stu = it.next();
System.out.println(stu +":"+tm.get(stu));
}
/*打印结果:zhangsan11:18:1
zhangsan32:28:2
zhangsan03:38:3
zhangsan23:38:2
*/
//2.将Map集合的映射关系存到集合中,这个关系的数据类型是Map.Entry,再 根据该类型的getKey()和gatValue()方法
Set<Map.Entry<Student, Integer>> entrySet = tm.entrySet();
Iterator<Map.Entry<Student, Integer>> ite = entrySet.iterator();
while(ite.hasNext())
{
Map.Entry<Student, Integer> me = ite.next();
Student key = me.getKey();
Integer value = me.getValue();
System.out.println(key +":" +value);
}
/*打印结果:zhangsan11:18:1
zhangsan32:28:2
zhangsan03:38:3
zhangsan23:38:2
*/
if(tm.containsKey(new Student("zhangsan23", 38)))
{
tm.remove(new Student("zhangsan23", 38));
}
System.out.println(tm);
//打印结果:{zhangsan11:18=1, zhangsan32:28=2, zhangsan03:38=3}
System.out.println(tm.get(new Student("zhangsan11", 18)));
//打印结果:1
}
}
//自定义比较器
class MyCompare implements Comparator<Student>
{
public int compare(Student s1, Student s2)
{
int com = s1.getAge() - (s2.getAge());
if(com > 0)
return 1;
else if(com < 0)
return -1;
else
return s1.getName().compareTo(s2.getName());
}
}
结构分析:
// 数组数据结构,Object[] elementData, 不同步
List list = new ArrayList();
// 数组数据结构,Object[] elementData, 同步
Vector vector = new Vector();
/*
链表结构,不同步
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
*/
LinkedList<Object> linkedList = new LinkedList<>();
// 不同步, 底层为 HashMap, HashMap 的 key 为存入set的元素,value 为 静态的 new Object()
Set set = new HashSet();
// 不同步,底层是 LinkedHashMap
LinkedHashSet<Object> linkedHashSet = new LinkedHashSet<>();
// 不同步,底层为 TreeMap, TreeMap 的 key 为存入set的元素,value为 静态的 new Object()
TreeSet<Object> treeSet = new TreeSet<>();
/*
不同步, 底层是Hash表数据结构, 允许 null key null value
Node<K,V>[] table
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
*/
Map map = new HashMap();
/*
同步,底层是Hash表数据结构,不允许 null key null value
Entry<?,?>[] table;
protected Entry(int hash, K key, V value, Entry<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
*/
Hashtable<Object, Object> hashtable = new Hashtable<>();
/*
底层是二叉树结构, 不同步
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
boolean color = BLACK;
}
*/
TreeMap<Object, Object> treeMap = new TreeMap<>();
/*
双向链表结构
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
*/
LinkedHashMap<Object, Object> linkedHashMap = new LinkedHashMap<>();
还没有评论,来说两句吧...