Collection 笔记
一、 Collection
所有集合共用的方法:
- ************************增************************
- boolean add(Object obj):添加一个元素
- boolean addAll(Collection collection):添加一个集合里面的所有元素
- ************************删************************
- void clear():清空集合内所有元素
- boolean remove(Object obj):删除一个指定元素
- boolean removeAll(Collection collection):删除与另外一个集合相同的所有元素
- ************************改************************
- boolean retainAll(Collection collection):保留与另外一个集合相同的所有元素,即做交集
- ************************查************************
- int size():获得集合的长度
- ************************判断************************
- boolean contains(Object obj):判断一个元素是否存在集合中
- boolean containsAll(Collection collection):判断一个集合是否包含另外一个集合的所有元素
- boolean isEmpty():判断一个集合是否为空
- ************************迭代器************************
- Iterator iterator():获得迭代器
二、 List 特点:有序可重复
List独有方法:
- ************************增************************
- boolean add(int index, Object obj):在指定位置添加一个元素
- boolean addAll(int index, Collection collection):添加一个集合里面的所有元素
- ************************删************************
- boolean remove(int index):根据索引删除一个元素
- ************************改************************
- Object set(int index, Object obj):设置索引处的元素值
- ************************查************************
- Object get(int index):获得指定位置元素
- int indexOf(Object obj):获得相应元素的位置
- ************************迭代************************
- ListIterator listIterator():获得ListIterator
三、 ArrayList(数组存储结构)
独有方法:
Object clone():复制ArrayList实例
四、 LinkList(链表存储结构)
独有方法:
- boolean addFirst(Object obj):在集合第一个添加一个元素
- boolean addLast(Object obj):在集合最后一个添加一个元素
- Object getFirst():获得第一个元素
- Object getLast():获得最后一个元素
- Object removeFirst():删除第一个元素
- Object removeLast():删除最后一个元素
新的替代方法:
- boolean offerFirst(Object obj):在集合第一个添加一个元素
- boolean offerLast(Object obj):在集合最后一个添加一个元素
- Object peekFirst():获得第一个元素
- Object peekLast():获得最后一个元素
- Object pollFirst():删除第一个元素
- Object pollLast():删除最后一个元素
/*在List里面,元素之间的比较使用equals()方法*/
五、 HashSet(哈希表存储) 特点:无序不可重复
检验HashSet里面元素比较方法:先调用HashCode()计算Hash值,再调用equals()方法比较Hash值一样的元素
import java.util.*;
class HashSetDemo
{
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Student("yuan01",17));
hs.add(new Student("yuan01",17));
hs.add(new Student("yuan02",21));
hs.add(new Student("yuan03",23));
hs.add(new Student("yuan04",32));
for(Iterator it = hs.iterator(); it.hasNext();) {
Student st = (Student)it.next();
sop(st.getName() + "..." + st.getAge());
}
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
class Student
{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public boolean equals(Object obj) {
if(!(obj instanceof Student)) {
return false;
}
Student st = (Student)obj;
System.out.println(this.name + "..equals.." + st.name);
return this.age == st.age && this.name.equals(st.name);
}
public int hashCode() {
//System.out.println(this.name + "hashCode()");
return 100;
//return name.hasCode + age * 20;
}
}
程序运行结果:
yuan01..equals..yuan01
yuan02..equals..yuan01
yuan03..equals..yuan02
yuan03..equals..yuan01
yuan04..equals..yuan03
yuan04..equals..yuan02
yuan04..equals..yuan01
可以看出由于所有的Hash值是相等的,所以相互之间进行比较,因此以后再使用HashSet的时候就需要重写hashCode()与equals()方法。
六、 TreeSet(二叉树又称红黑树存储) 特点:有序不可重复
若要向TreeSet里面存入自定义元素,则自定义类必须实现Comparable接口,重写compareTo()方法。如果有类里面有多个元素则在判断父元素后,还要判断子元素。
import java.util.*;
class TreeSetDemo1
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add(new Person("yuan01", 20));
ts.add(new Person("yuan02", 17));
ts.add(new Person("yuan03", 19));
ts.add(new Person("yuan04", 20));
for(Iterator it = ts.iterator(); it.hasNext();) {
Person st = (Person)it.next();
System.out.println(st.getName() + "..." + st.getAge());
}
}
}
class Person implements Comparable
{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}//重写compareTo()方法
public int compareTo(Object obj) {
Person ps = (Person)obj;
if(this.age > ps.age)
return 1;
if(this.age == ps.age) {
return this.name.compareTo(ps.name);
}
return -1;
}
}
七、 使用比较器进行比较(实际中应用较多)
如果不想使用已经定义好的比较方法,可以自定义比较器,即实现Comparator接口,重写compare()方法,实例化一个类对象,当作参数传入TreeSet的构造方法中。
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(new myCompare());
ts.add("asdf");
ts.add("afggf");
ts.add("aasdfasdf");
ts.add("asd");
ts.add("acd");
for(Iterator it = ts.iterator(); it.hasNext();) {
String str = (String)it.next();
System.out.println(str);
}
}
}
class myCompare implements Comparator {
public int compare(Object o1, Object o2) {
String s1 = (String)o1;
String s2 = (String)o2;
//System.out.println(s1 + "..compare.." + s2);
int l1 = s1.length();
int l2 = s2.length();
if(l1 > l2)
return 1;
if(l1 == l2)
return s1.compareTo(s2);//当长度一样的时候,还要比较内容
return -1;
}
}
如果两种比较都有的时候,以比较器为主。
八、 泛型
import java.util.*;
class GenericDemo
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("yuan01");
al.add("yuan02");
al.add("yuan03");
al.add("yuan04");
for(Iterator<String> it = al.iterator(); it.hasNext();) {
String str = it.next();
System.out.println(str);
}
}
}
泛型在比较器中的使用:
import java.util.*;
class GenericDemo2
{
public static void main(String[] args)
{
TreeSet<String> ts = new TreeSet<String>(new StrComparator());
ts.add("java0");
ts.add("java02");
ts.add("java");
for(Iterator<String> it = ts.iterator(); it.hasNext();) {
String str = it.next();
System.out.println(str);
}
}
}
class StrComparator implements Comparator<String>
{
public int compare(String s1 , String s2) {
int num = ((Integer)s2.length()).compareTo((Integer)s1.length());
if(num == 0)
return s2.compareTo(s1);
return num;
}
}
自定义泛型类(当自定义类中,使用对象的类型不确定的时候,早期使用Object,现在使用泛型)
class GenericDemo3
{
public static void main(String[] args)
{
Tool<String> tool = new Tool<String>();
tool.setObject("loveyuan");
System.out.println(tool.getObject());
}
}
class Tool<T>
{
private T t;
public void setObject(T t) {
this.t = t;
}
public T getObject() {
return t;
}
}
当只定义泛型类的时候,一个类难以操作多个不同类型的变量,而定义泛型方法可以做一个类操作多个不同对象。
class GenericDemo4
{
public static void main(String[] args)
{
Demo<String> d = new Demo<String>();
d.show("love");
d.print(new Integer(1));
d.print("yuan");
}
}
class Demo<T>
{
public void show(T t) {
System.out.println("show" + t);
}
public <Q> void print(Q q) {
System.out.println("print" + q);
}
}
特殊之处:静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。而且泛型的标记<T>等应该放在方法返回类型的前面,修饰词的后面。
九、 泛型的高级应用
当方法里面的参数类型不确定的时候,可以使用通配符?代替不明确的参数,与使用其它符号如<T>等不同的是,使用通配符,不能取出相应的元素,而使用其它符号可以,例如:T t = it.next();其中T就是明确的了。
import java.util.*;
class GenericDemo6
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("java1");
al.add("java2");
al.add("java3");
ArrayList<Integer> al1 = new ArrayList<Integer>();
al1.add(1);
al1.add(2);
al1.add(3);
print(al);
}
public static void print(ArrayList<?> al) {
for(Iterator<?> it = al.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}
如果当要操作的对象有继承关系的时候,子类对象不能向父类对象转换,例子如下:
import java.util.*;
class People
{
private String name;
public People(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Teacher extends People
{
public Teacher(String name) {
super(name);
}
}
class GenericDemo7
{
public static void main(String[] args)
{
ArrayList<Teacher> al = new ArrayList<Teacher>();
al.add(new Teacher("java1"));
al.add(new Teacher("java2"));
al.add(new Teacher("java3"));
printAll(al);
}
public static void printAll(ArrayList<People> al) {
for(Iterator<People> it = al.iterator(); it.hasNext();) {
System.out.println(it.next().getName());
}
}
}
编译时,报错说无法通过方法调用转换将实际参数ArrayList<Teacher>转换为ArrayList<People>,那么怎样修改呢 ?可以使用通配符<? extends People>代替即可解决问题,这个叫作泛型的上限。修改后例子如下:
public static void printAll(ArrayList<? extends People> al) {
for(Iterator<? extends People> it = al.iterator(); it.hasNext();) {
System.out.println(it.next().getName());
}
}
泛型的下限:<? super E>可以接受E的所有父类型。
class GenericDemo7
{
public static void main(String[] args)
{
ArrayList<People> al = new ArrayList<People>();
al.add(new People("java--1"));
al.add(new People("java--2"));
al.add(new People("java--3"));
printAll(al);
}
public static void printAll(ArrayList<? super Teacher> al) {
for(Iterator<? super Teacher> it = al.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}
十、 Map(存储键值对)
- void clear():清空元素
- boolean containsKey(Object obj):判断是否存在键
- boolean containsValue(Object value):判断是否存在值
- Object get(Object key):根据键获得值
- Set keySet():获得所有键所组成的Set集合
- Object put(Key key , Value value):存储元素
- Collection values():获得Collection
|--Hashtable:是哈希表数据结构。不允许存储null键null值,是线程同步的,
|--HashMap:是只哈希表数据结构。允许存储null键null值,不是线程同步的。
|--TreeMap:是二叉树数据结构,是线程不同步的。可用Map中的键进行排序。
十一、 Map中获取键值的方法
第一种:values()获取所有的值,返回的对象是Collection类型
import java.util.*;
class MapDemo1
{
public static void main(String[] args)
{
Map<String , String> map = new HashMap<String, String>();
map.put("01","java01");
map.put("02","java02");
map.put("03","java03");
System.out.println(map.values());
}
}
第二种:keySet()方法获得所有的键,再通过键获取所有的值
import java.util.*;
class MapDemo2
{
public static void main(String[] args)
{
Map<String ,String> map = new HashMap<String , String>();
map.put("01","java1");
map.put("02","java2");
map.put("03","java3");
Set<String> set = map.keySet();
for(Iterator<String> it = set.iterator();it.hasNext();) {
String key = it.next();
String value = map.get(key);
System.out.println(key + "=" + value);
}
}
}
第三种:entrySet()方法,获取所有的键值关系,存入Set<Map.Entry<key,value>>里面,通过getKey()和getValue()方法获得相应的键和值。
import java.util.*;
class MapDemo3
{
public static void main(String[] args)
{
Map<String , String> map = new HashMap<String , String>();
map.put("01","java1");
map.put("02","java2");
map.put("03","java3");
Set<Map.Entry<String,String>> set = map.entrySet();
for(Iterator<Map.Entry<String,String>> it = set.iterator();it.hasNext();) {
Map.Entry<String,String> me = it.next();
String key = me.getKey();
String value = me.getValue();
System.out.println(key + "=" + value);
}
}
}
十二、 TreeMap的应用
import java.util.*;
class MapDemo4
{
public static void main(String[] args)
{
TreeMap<Student, String> map = new TreeMap<Student, String>();
map.put(new Student("java17",20),"beijing");
map.put(new Student("java13",20),"shanghai");
map.put(new Student("java16",20),"wuhan");
map.put(new Student("java12",20),"nanjing");
Set<Map.Entry<Student,String>> set = map.entrySet();
for(Iterator<Map.Entry<Student,String>> it = set.iterator();it.hasNext();) {
Map.Entry<Student,String> me = it.next();
Student st = me.getKey();
String addr = me.getValue();
System.out.println(st + "=" + addr);
}
}
}
class Student implements Comparable<Student>
{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int hashCode() {
return name.hashCode() + age * 23;
}
public boolean equals(Object obj) {
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配!");
Student st = (Student)obj;
return this.name.equals(st.name) && this.age == st.age;
}
public int compareTo(Student st) {
int num = ((Integer)this.age).compareTo((Integer)st.age);
if(num == 0)
return this.name.compareTo(st.name);
return num;
}
public String toString() {
return this.name + ":" + this.age;
}
}
当自定义的对象要存入Hash存储结构的集合中时,需要重写hashCode()和equals()方法,当要存入二叉树数据结构时,要实现Comparable接口或者自定义比较器实现Comparator接口,并当参数传入相应集合的构造方法中。
*******#***反向旋转比较器Comparator<Student> cmp = Collections.reverseOrder();*************