集合
Collection
接口java.util.Collection
包含許多對集合的操作方法
常用實現類:
ArrayList
List 接口的大小可變數組的實現。實現了所有可選列表操作,並允許包括 null 在內的所有元素。除了實現 List 接口外,此類還提供一些方法來操作內部用來存儲列表的數組的大小。(此類大致上等同於 Vector 類,除了此類是不同步的。)
添加修改元素
boolean add(E e)
將指定的元素添加到此列表的尾部。void add(int index, E element)
將指定的元素插入此列表中的指定位置。boolean addAll(Collection < ? extends E> c)
按照指定 collection 的迭代器所返回的元素順序,將該 collection 中的所有元素添加到此列表的尾部。boolean addAll(int index, Collection< ? extends E> c)
從指定的位置開始,將指定 collection 中的所有元素插入到此列表中。E set(int index, E element)
用指定的元素替代此列表中指定位置上的元素。
刪除元素
E remove(int index)
移除此列表中指定位置上的元素。boolean remove(Object o)
移除此列表中首次出現的指定元素(如果存在)。public boolean removeAll(Collection< ?> c)
移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作)。此調用返回後,collection 中將不包含任何與指定 collection 相同的元素。void clear()
移除此列表中的所有元素。
獲取
E get(int index)
返回此列表中指定位置上的元素。int size()
返回此列表中的元素數。boolean isEmpty()
如果此列表中沒有元素,則返回 trueint lastIndexOf(Object o)
返回此列表中最後一次出現的指定元素的索引,或如果此列表不包含索引,則返回 -1。boolean contains(Object o)
如果此列表中包含指定的元素,則返回 true。public boolean retainAll(Collection< ?> c)
僅保留此 collection 中那些也包含在指定 collection 的元素(可選操作)。換句話說,移除此 collection 中未包含在指定 collection 中的所有元素。
獲取迭代器
- public Iterator< E> iterator()
返回以恰當順序在此列表的元素上進行迭代的迭代器。
- 方法摘要
- boolean hasNext()
如果仍有元素可以迭代,則返回 true。 - E next()
返回迭代的下一個元素。 - void remove()
從迭代器指向的 collection 中移除迭代器返回的最後一個元素(可選操作)。
集合演示
import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{
//method_1();
//method_2();
get();
}
public static void get()
{
ArrayList al=new ArrayList();
//1.添加元素
al.add("今天");
al.add("天氣");
al.add("很好");
/* Iterator it = al.iterator();//獲取迭代器用於取出集合中的元素
while(it.hasNext())
{
sop(it.next());
} */
for(Iterator it = al.iterator();it.hasNext();)
{
sop(it.next());
}
}
public static void method_1()
{
//創建一個集合容器。使用Collecion接口的子類.ArrayList
ArrayList al=new ArrayList();
ArrayList al2=new ArrayList();
//1.添加元素
al.add("今天");
al.add("天氣");
al.add("很好");
al2.add("今天");
al2.add("心情");
al2.add("很好");
sop("al:"+al);
sop("al2:"+al2);
sop("alsize:"+al.size());
al.retainAll(al2);//取交集
sop("al:"+al);
sop("al2:"+al2);
sop("alsize:"+al.size());
}
public static void method_2()
{
ArrayList al=new ArrayList();
ArrayList al2=new ArrayList();
al.add("今天的");
al.add("天氣");
al.add("很好");
al.add("!");
al2.add("今天");
al2.add("心情");
al2.add("很好");
al2.add("!");
sop("al:"+al);
sop("al2:"+al2);
al.remove("天氣");
sop("al.remove(\"天氣\")");
sop("al:"+al);
al.removeAll(al2);
sop("al.removeAll(al2)");
sop("al:"+al);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
get方法輸出:
今天
天氣
很好
method_1輸出:
al:[今天, 天氣, 很好]
al2:[今天, 心情, 很好]
alsize:3
al:[今天, 很好]
al2:[今天, 心情, 很好]
alsize:2
method_2輸出:
al:[今天的, 天氣, 很好, !]
al2:[今天, 心情, 很好, !]
al.remove(“天氣”)
al:[今天的, 很好, !]
al.removeAll(al2)
al:[今天的]
List集合共性方法
Collection
- List:元素是有序的,元素可以重複。因爲該集合體繫有索引。
- ArrayList:底層的數據結構使用的是數組結構.特點:查詢很快,增刪稍慢.線程不同步.
- LinkedList:底層使用的鏈表數據結構.特點:查詢稍慢,增刪很快.
- Vector:底層是數組數據結構。線程同步。被ArrayList替代了.
- Set元素是無序的,元素不可以重複。
- -
List:
- 特有方法,凡是可以操作角標的方法都是該體系特有的方法。
增
add(index,element);
addAll(index,Collection);
刪
remove(index);
改
set(index,element);
查
get(index);
subList(from,to);
listIterator();
import java.util.*;
class ListDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
ArrayList al=new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
sop("原集合是:"+al);
//在指定位置添加元素
al.add(1,"java09");
sop(al);
//刪除指定位置的元素
al.remove(2);
sop(al);
//修改元素
al.set(2,"java07");
sop(al);
sop("get(1):"+al.get(1));
for(int x=0;x<al.size();x++)//通過循環獲取List中的元素
{
sop("al("+x+")="+al.get(x));
}
for(Iterator it=al.iterator();it.hasNext();)//通過迭代器獲取元素
{
sop(it.next());
}
}
}
ListIterator 迭代器
List集合特有的迭代器。ListIterator是Iterator的子接口。
在迭代時不可以通過集合對象的方法操作集合中的元素
因爲會發生併發修改異常ConcurrentModificationException
所以,在迭代器時,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能對元素進行判斷,取出,刪除的操作。
如果想要其他的操作,如:添加,修改等,就需要使用其子接口,ListIterator。
該接口只能通過List集合的ListIterator方法獲取.
public static void main(String[] args)
{
//演示列表迭代器
ArrayList al=new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
sop("原列表:"+al);
//在迭代過程中,準備添加或者刪除元素
for(Iterator it=al.iterator();it.hasNext();)//通過迭代器獲取元素
{
Object obj = it.next();
if(obj.equals("java02"))
{
//al.add("java008"); 運行時錯誤,不允許併發修改列表
it.remove();//將java02的引用從集合中刪除了
}
//sop("obj="+obj);
}
sop("通過iterator迭代器刪除java02");
sop(al);
sop("恢復原列表");
al.add(1,"java02");
sop(al);
ListIterator lit=al.listIterator();
for(;lit.hasNext();)
{
Object obj=lit.next();
if(obj.equals("java02"))
{
lit.set("java10");
lit.add("java11");//插入元素到當前元素之後
}
}
sop("通過ListIterator.set修改java02爲java10");
sop(al);
for(;lit.hasPrevious();)//向前判斷
{
sop(lit.previous());//倒序輸出
}
}
Vector 矢量
import java.util.*;
/*
枚舉就是Vector特有的取出方式.
枚舉和迭代器很像
其實枚舉和迭代是一樣的
因爲枚舉的名稱以及方法的名稱都過長
所以被迭代器取代了
*/
class VectorDemo
{
public static void main(String[] args)
{
Vector v=new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");
Enumeration en=v.elements();
while(en.hasMoreElements())
{
System.out.println(en.nextElement());
}
}
}
類 LinkedList< E> 鏈表
import java.util.*;
/*
LinkedList:特有方法:
addFirst();
addLast();
getFirst();
getLast();
removeFirst();
removeLast();
*/
class LinkedListDemo
{
public static void main(String[] args)
{
LinkedList ll=new LinkedList();
ll.addFirst("java01");
ll.addLast("java02");
ll.addLast("java03");
ll.addLast("java04");
ll.offerFirst("java00");//插入第一個元素
sop(ll.peekLast());//獲取最後一個元素,不刪除
sop(ll.pollLast());//獲取並刪除最後一個元素
sop(ll);
sop("First:"+ll.getFirst());
sop("Last:"+ll.getLast());
sop("remove:"+ll.removeFirst());
sop("size:"+ll.size());
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
HashSet 哈希表
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable
//此類實現 Set 接口,由哈希表(實際上是一個 HashMap 實例)支持。它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。
public interface Set<E> extends Collection<E>
//一個不包含重複元素的 collection。
方法摘要
boolean add(E e)
如果此 set 中尚未包含指定元素,則添加指定元素。
- Set:元素是無序(存入和取出的順序不一定一致),元素不可以重複。
- HashSet:底層數據結構是哈希表
- HashSet 是如何保證元素唯一性的呢?
- 是通過元素的兩個方法,hashCode和equals來完成
- 如果元素的HashCode值相同,纔會判斷equals是否爲true
- 如果元素的hashcode值不同,不會調用equals。
- 對於判斷元素是否存在,以及刪除等操作,依賴的方法是元素的hashcode和equals方法。
- TreeSet:
Set集合的功能和Collection是一致的。
import java.util.*;
class HashSetTest
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a4",14));
hs.add(new Person("a1",11));
Iterator it=hs.iterator();
while(it.hasNext())
{
Person p=(Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
}
class Person{
private String name;
private int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public int hashCode()
{
System.out.println(this.name+"hashCode");
return name.hashCode()+age*2;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p=(Person)obj;
System.out.println(this.name+"...equals..."+p.name);
return this.name.equals(p.name) && this.age==p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
輸出:
a1hashCode
a2hashCode
a3hashCode
a4hashCode
a1hashCode
a1…equals…a1
a1::11
a2::12
a3::13
a4::14
TreeSet 二叉樹表
HashSet: 數據結構是哈希表。線程是非同步的。
保證元素唯一性的原理:判斷元素的hashCode值是否相同。
如果相同,還會繼續判斷元素的equals方法,是否爲true。TreeSet:可以對Set集合中的元素進行排序。
- 底層數據結構是二叉樹
保證元素唯一性的依據:compareTo方法return 0.
- TreeSet排序的第一種方式:讓元素自身具備比較性。
元素需要實現Comparable接口,覆蓋compareTo方法.
這種方式也稱爲元素的自然順序,或者叫做默認順序。 - TreeSet的第二種排序方式:
當元素自身不具備比較性時,或者具備的比較性不是所需要的。
這時就需要讓集合自身具備比較性。創建比較器,並讓集合容器使用這個比較器進行比較。
- TreeSet排序的第一種方式:讓元素自身具備比較性。
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet();
ts.add("efg");
ts.add("abc");
ts.add("bcd");
Iterator it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
輸出:
abc
bcd
efg
1.TreeSet 對象自身的可比較性
TreeSet存儲自定義對象
TreeSet添加的對象實現 Comparable接口
實現int compareTo()方法
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi01",40));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi08",19));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student st=(Student) it.next();
System.out.println(st.getName()+"--"+st.getAge());
}
}
}
class Student implements Comparable//該接口強制讓學生具備比較性
{
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;
}
//排序時,當主要條件相同時,一定要判斷一下次要條件
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是學生對象");
Student s=(Student)obj;
System.out.println(this.name+"...compareto..."+s.name);
if(this.age>s.age)
return 1;
else if(this.age==s.age)
return this.name.compareTo(s.name);
else
return -1;
}
}
2.TreeSet 使用 Comparator接口 創建比較器
import java.util.*;
/*
當元素自身不具備比較性,或者具備的比較性不是所需要的。
這時需要讓容器自身具備比較性。
定義了比較器,將比較器對象作爲參數傳遞給TreeSet集合的構造函數
當兩種排序都存在時,以比較器爲主。
定義一個類,實現Comparator接口,覆蓋compare方法。
*/
class MyComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
if(!((o1 instanceof Student)&&(o2 instanceof Student)))
throw new ClassCastException("不是學生對象!");
Student t1=(Student)o1;
Student t2=(Student)o2;
if(t1.getAge()>t2.getAge())
return 1;
else if(t1.getAge()<t2.getAge())
return -1;
else
{
return t1.getName().compareTo(t2.getName());
}
}
}
class TreeSetDemo2
{
public static void main(String[] args)
{
MyComparator mc=new MyComparator();
TreeSet ts=new TreeSet(mc);
ts.add(new Student("lili",25));
ts.add(new Student("koko",27));
ts.add(new Student("titi",18));
ts.add(new Student("lili",25));
Iterator it=ts.iterator();
while(it.hasNext())
{
Student s=(Student)it.next();
System.out.println(s.getName()+"--"+s.getAge());
}
}
}
class 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;
}
}
3.TreeSet 練習
將String類型的元素存入TreeSet容器,根據字符串長度進行排序
創建一個比較器,比較字符串長度
使用迭代器輸出
import java.util.*;
class StringLenComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
if(!((o1 instanceof String)&&(o2 instanceof String)))
throw new ClassCastException("傳入的不是字符串");
String s1=(String)o1;
String s2=(String)o2;
if(s1.length()>s2.length())
return 1;
if(s1.length()<s2.length())
return -1;
return s1.compareTo(s2);
}
}
class TreeSetTest
{
public static void main(String[] args)
{
StringLenComparator slc=new StringLenComparator();//創建比較器
TreeSet ts=new TreeSet(slc);//創建二叉樹容器,使用slc比較器
ts.add("hello");
ts.add("java");
ts.add("hi");
ts.add("world!");
ts.add("hi");//添加元素
Iterator it=ts.iterator();//創建迭代器.使用ts容器的迭代器
while(it.hasNext())
{
System.out.println(it.next());
}
}
}