集合框架
集合只用于存储对象,长度可变化
数组和集合类同是容器,有何不同?
数组即可存储对象,也可以存储基本数据类型,长度固定
集合只可以存储对象,长度可变
Collection
|--List:该集合体系按照存入顺序存储,可以有重复元素
|--Arraylist:数组
|--LinkedList:链表
|--Vector:数组
|--Set:该集合体系没有索引,会按照特定的数据结构存放数据,并不是存入顺序存储,不允许重复元素
|--HashSet:哈希表
|--TreeSet:二叉树
ArrayList和Vector的区别:
Vector线程同步,效率低,现已被ArrayList替代
ArrayList线程不同步,效率要比Vector高
ArrayList和LinkedList的区别(动态数组和链表的区别):
ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构
对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针
对于add和remove操作,LinkedList比较占优势,因为ArrayList要移动数据
Collection
Interface Collection是List、Set和Queue接口的父接口,提供了操作集合的基本方法
Method:
boolean add(E e)
void clear() //清除集合中的所有元素
boolean contains(Object o)
boolean isEmpty()
Iterator iterator() //返回一个Iterator对象,用于遍历集合里的元素
boolean remove(Object o) //删除集合中指定元素
int size() //返回元素个数
object[] toArray() //集合转数组
<T> T[] toArray(T[] a)
boolean retainAll(Collection<?> c) //取交集,放入当前集合中(调用方法的集合对象)
Iterator
Iterator对象被称为迭代器,用于迭代访问集合中的元素
Method:
boolean hasNext()
E next()
void remove()
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collection;
/**
迭代器
*/
class IteratorTest
{
public static void main(String[] args)
{
Collection<String> c = new ArrayList<String>();
c.add("a1");
c.add("a2");
c.add("a3");
c.add("a4");
c.add("a5");
for(Iterator<String> it = c.iterator(); it.hasNext();)
{
String str = it.next();
System.out.println(str);
if("a1".equals(str))
{
it.remove();
}
}
System.out.println("--------------------");
System.out.println(c);
}
}
集合在迭代过程中,不能被修改,否则会引发ConcurrentModificationException异常
List集合
List集合按照元素的存入顺序存入数据,且存在索引,因此List集合可以通过索引操作集合元素
增
boolean add(E e)
void add(int index, E element)
boolean addAll(Collection<? extends E>)
删
E remove(int index)
改
E set(int index, E element)
查
E get(int index)
int lastIndexOf(Object o)
List<E> subList(int fromIndex, int toIndex) //注意此方法,对返回集合的操作就是对原集合的操作
ListIterator
List与Set集合都可以使用Iterator迭代器遍历元素,但List提供了一个更适用与List集合的ListIterator接口,用于迭代List集合,ListIterator接口继承了Iterator接口,提供了额外方法操作List集合
List接口的listIterator()方法返回ListIterator对象
boolean hasPervious() //返回该迭代器关联的集合是否还有上一个元素
E previous() //返回该迭代器的上一个元素
void add(E e) //在指定位置插入一个元素
void set(E e) //替换元素
ListIterator与普通Iterator进行对比:
ListIterator增加了向前迭代的功能(Iterator只能向后迭代)
ListIterator还可以添加、修改元素(Iterator只能删除元素)
ArrayList和Vector
ArrayList和Vector都是基于数组数据结构的List实现类,ArrayList和Vector内部封装了一个动态再分配的Object[]数组
ArrayList线程不安全,Collections工具类可以ArrayList集合变为线程安全
Vector线程安全,效率低
import java.util.*;
/**
ArrayList
*/
class ArrayListTest
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("a1");
al.add("a3");
al.add("a2");
//正向迭代
for(ListIterator<String> li = al.listIterator(); li.hasNext(); )
{
System.out.println(li.next());
}
//指针如果在集合首位,反向迭代是找不到元素的
for(ListIterator<String> li = al.listIterator(); li.hasPrevious(); )
{
String str = li.previous();
if("a2".equals(str))
{
li.add("a4");
}
System.out.println(str);
}
}
}
LinkedList
LinkedList内部以链表的形式来保存集合中的元素,因此随机访问集合元素时性能较差,但在插入、删除元素时性能非常出色
method:
void addFirst(E e)
void addLast(E e)
E getFirst(E e) //如果集合为空,报异常
E getLast(E e) //如果集合为空,报异常
E removeFirst(E e) //如果集合为空,报异常
E removeLast(E e) //如果集合为空,报异常
6.0新方法:
boolean offerFirst(E e) //在头部添加元素
boolean offerLast(E e) //在尾部添加元素
E peekFirst() //返回第一个元素,如果集合为空,返回null
E peeklast() //返回最后一个元素,如果集合为空,返回null
E poolFirst() //移除第一个元素,如果集合为空,返回null
E poolLast() //移除最后一个元素,如果集合为空,返回null
Set集合
Set集合没有索引,不允许重复元素,会按照数据结构存放数据
Set集合继承Collection的方法,没有提供任何额外的方法
HashSet
HashSet按Hash算法存储集合中的元素,Hash表有很好的存取和查找性能
HashSet具有以下特点:
1)不会保证元素的排列顺序,元素的位置据hashCode值而定
2)不同步
3)元素值可以是null
向HashSet存入一个元素的过程
当向HashSet集合中存入一个元素时,会先调用对象的hashCode()方法获取hashCode值,根据hashCode值来决定该对象在HashSet中的存储位置,如果hashCode值相同,再调用equals方法判断是否相同,如果equals方法返回false,说明不相同,可以存储,否则是相同元素,不可以存储
注意:
当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,contatins方法会检索不到对象,也无法从HashSet集合中单独删除当前对象,从而造成内存泄漏
TreeSet
TreeSet默认会对元素进行自然排序(二叉树结构),也可以定制排序(关联比较器)
不允许存放相同元素,判断元素是否相同使用的自然排序或者比较器(如果存在)
自然排序
TreeSet会调用集合元素的compareTo(T o)方法来比较元素之间大小关系,将集合元素按升序排序,这种方式就是自然排序
Java提供了一个Comparable<T>接口,该接口里定义了一个int compareTo(T o)方法,一个类要实现自然排序,必须要实现该接口,覆写该方法
Java的一些常用类具备自然排序特征(即实现了Comparable接口),如String、Integer、Data、Time
import java.util.TreeSet;
import java.util.Date;
/**
因为TreeSet默认会对元素进行比较,而只有相同类型的元素才有可比性
所以TreeSet最好加上泛型,否则会因为类型不同报异常
*/
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add("sdf");
ts.add(new Date()); //运行时报ClassCastException异常
//如果使用泛型,上面的问题也就不存在了
TreeSet<String> ts2 = new TreeSet<String>();
ts2.add("adf");
ts2.add("fds");
}
}
定制排序
TreeSet在创建对象时,可以关联一个比较器,优先使用比较器的比较方式
TreeSet<E>构造方法:TreeSet(Comparator<? super E> comparator) //限定Comparator的泛型为E或者E的父类
import java.util.TreeSet;
import java.util.Comparator;
import java.util.Iterator;
/**
定制排序,创建TreeSet时传入一个比较器,并覆写compare方法
*/
class Person
{
private int age;
public Person(int age)
{
this.age = age;
}
public int getAge()
{
return age;
}
}
class TreeSetTest2
{
public static void main(String[] args)
{
//TreeSet关联一个比较器,并覆写比较器中的compare方法
TreeSet<Person> ts = new TreeSet<Person>(new Comparator<Person>()
{
@Override
public int compare(Person p1, Person p2)
{
//使用了Integer本来具有的比较特性(Integer实现Comparable接口,并覆写了compareTo方法,且该方法是升序排序)
return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));
}
});
//在添加元素的过程中,已经使用传入的比较器完成了比较
ts.add(new Person(5));
ts.add(new Person(6));
ts.add(new Person(4));
//顺序输出TreeSet中每个人的年龄
for(Iterator<Person> it = ts.iterator(); it.hasNext();)
{
System.out.println(it.next().getAge());
}
}
}
Map集合
Map用于保存具有映射关系的数据,一组key、一组value如果存入的key相同,后面的会覆盖前面的,所以Map集合中不存在相同的key
Method:
V put(K key, V value) //如果key相同,后添加的会覆盖原来的键值对,并返回原来键值对的value,如果原来不存在此key的键值对,则返回null
void putAll(Map<? extends K, ? extends V> m)
void clear() //删除该Map对象中所有key-value对
V remove(Object key) //删除指定key所对应的key-value对
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
V get(Object key) //根据key,获取对应的value
int size()
Collection<V> values() //返回该Map里所有value组成的Collection
Set<K> keySet() //返回该Map中所有key所组成的Set集合
Set<Map.Entry<K, V>> entrySet() //返回Map中所包含的key-value对所组成的Set集合,每个集合元素都是Map.Entry(Entry是Map的内部接口)对象
HashMap与Hashtable
HashMap:底层是哈希表数据结构,允许使用null键null值。线程不同步,效率高。jdk1.2
Hashtable:底层是哈希表数据结构,不可以存入null键null值。线程同步,效率底。jdk1.0
key不允许重复,哈希结构判断相同使用的是hashcode()和equals(Object)方法,所以作为key的元素要覆写这两个方法
import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;
/**
定义学生类,有姓名、年龄两个属性
HashMap中key为学生对象,value为住址address
注意:姓名和年龄相同的视为同一个学生,保证学生的唯一性
*/
//二叉树数据结构需要自然排序,哈希表使用hashCode()和equals()方法
//此学生类对象即可以存入二叉树数据结构,也需要存入哈希表中
class Student implements Comparable<Student>
{
private String name;
private int age;
Student(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
@Override
public String toString()
{
return name+"---"+age;
}
//哈希表数据结构判断元素是否相同使用的方法
@Override
public int hashCode()
{
return name.hashCode() + age*15;
}
//哈希表数据结构判断元素是否相同使用的方法
@Override
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
{
throw new ClassCastException("不是Student类型");
}
Student stu = (Student)obj;
return name.equals(stu.getName()) && age==stu.getAge();
}
//二叉树数据结构默认使用的比较依据
@Override
public int compareTo(Student stu)
{
int num = name.compareTo(stu.getName());
if(num == 0)
{
num = new Integer(age).compareTo(new Integer(stu.getAge()));
}
return num;
}
}
class HashMapTest
{
public static void main(String[] args)
{
HashMap<Student, String> hs = new HashMap<Student, String>();
hs.put(new Student("zhangsan", 17), "beijing");
//姓名、年龄相同视为同一个学生
hs.put(new Student("zhangsan", 17), "shanghai");
hs.put(new Student("lisi", 17), "shanghai");
hs.put(new Student("wangwu", 17), "nanjing");
hs.put(new Student("zhaoliu", 17), "tianjin");
//获取所有key到Set集合中
Set<Student> keySet = hs.keySet();
for(Iterator<Student> it = keySet.iterator(); it.hasNext(); )
{
Student stu = it.next();
//根据key获取value
String address = hs.get(stu);
System.out.println(stu.getName()+"---"+address);
}
//另外一种输出HashMap集合中元素的方法
System.out.println("-----------------------------------");
Set<Map.Entry<Student, String>> entrySet = hs.entrySet();
for(Map.Entry<Student, String> ele : entrySet)
{
System.out.println(ele.getKey() + "---" + ele.getValue());
}
}
}
TreeMap
使用了二叉树数据结构,默认会对key自然排序,也可以在创建TreeMap实例时传入比较器
不允许存在相同key,判断元素是否相同使用的是自然排序或者比较器
import java.util.*;
/**
获取字符串中各个字母出现的次数
输出格式:a(个数)b(个数)...
*/
class TreeMapTest
{
public static void main(String[] args)
{
String str = method_1("adflkjld,.,.,flksajdf");
System.out.println(str);
}
public static String method_1(String str)
{
char[] chr = str.toCharArray();
TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
for(int i = 0; i < chr.length; i++)
{
//如果不是字母就跳过
if(!((chr[i] >= 'a' && chr[i] <= 'z') || (chr[i] >= 'A' && chr[i] <= 'Z')))
continue;
Integer count = tm.get(chr[i]);
if(count == null)
tm.put(chr[i], 1);
else
tm.put(chr[i], ++count);
}
StringBuilder sb = new StringBuilder();
Set<Map.Entry<Character, Integer>> entrySet = tm.entrySet();
for(Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator(); it.hasNext(); )
{
Map.Entry mapEntry = it.next();
sb.append(mapEntry.getKey()+"("+mapEntry.getValue()+")");
}
return sb.toString();
}
}
Collections工具类
数组提供了Arrays工具类,包含的全部是静态方法集合提供了Collections工具类,包含的全部是静态方法
Collections,提供了一些方法对集合元素进行排序、查询和修改、实现同步等
排序操作
static <T extends Comparable<? super T>> void sort(List<T> list) //对List中元素进行自然排序(前提是元素有排序性)
static <T> void sort(List<T> list, Comparator<? super T> c) //使用比较器对List中元素进行排序
static void reverse(List<?> list) //反转指定List集合中元素的顺序
static void shuffle(List<?> list) //对List集合元素进行随机排序(模拟洗牌动作)
static <T> Comparator<T> reverseOrder() //反转自然顺序
static <T> Comparator<T> reverseOrder(Comparator<T> cmp) //反转比较器cmp的顺序
class ReverseOrderTest
{
public static void main(String[] args)
{
//反转自然顺序
//TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder());
//反转比较器的顺序
TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new Com()));
ts.add("asdlkf");
ts.add("fsdl");
ts.add("dsdkf");
ts.add("kf");
ts.add("bf");
ts.add("af");
System.out.println(ts);
}
}
//定义一个比较器
class Com implements Comparator<String>
{
@Override
public int compare(String st1, String st2)
{
int num =st1.length()-st2.length();
if(num == 0)
{
return st1.compareTo(st2);
}
return num;
}
}
查找、替换操作
static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) //返回最大值(前提是可自然排序)
static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) //使用二分搜索法,在list中搜索key,并返回索引,必须保证List处于有序状态
static void fill(List<? super T> list, T obj) //使用指定元素obj替换指定List集合中的所有元素
static <T> boolean replaceAll(List<T> list, T oldVal, T new Val)
public static void main(String[] args)
{
//创建四个同步的集合对象
Collection c = Collections.synchronizedCollection(new ArrayList());
List list = Collections.synchronizedList(new ArrayList());
Set s = Collections.synchronizedSet(new HashSet());
Map m = Collections.synchronizedMap(new HashMap());
}
数组与集合的相互转换
数组转集合,Arrays提供如下方法:static <T> List<T> asList(T... a)
注意:如果数组中存储的基本数据类型,asList会将数组整体作为一个元素存入集合
集合转数组,Collection提供如下两个方法:
Object[] toArray()
<T> T[] toArray(T[] a)
---------------------- ASP.Net+Android+IOS开发</a>、 .Net培训、期待与您交流! ----------------------