集合框架
基本的集合框架如下:
而我們常見的幾種集合框架如下:
、
一、基本操作
基本操作爲增、刪、改;
1.獲取個數,集合長度.
sop("size:"+a1.size());
2.刪除元素
a1.remove("test02");//刪除集合內的某個對象.
sop(a1);
a1.clear();//清空集合.
3.判斷
sop("test03是否存在:"+a1.contains("test03"));
sop("是否爲空?"+a1.isEmpty());
4.取交集
a1.retainAll(a2);//取交集,只保留a1和a2中相同的元素
二、迭代器
迭代器:
/*
1. add方法的參數類型是object。以便於接受任何實體對象。
2. 集合中存儲的都是對象的地址。
3. 迭代是取出集合中元素的一種方式。 對於集合的元素取出這個動作:當不足以用一個函數來描述,需要用多個功能來體現,所以就將取出這個動作封裝成一個對象來描述。就把取出方式定義在集合的內部,這樣取出方式就可以直接訪問集合內部的元素。
那麼取出方式就被定義成了內部類。而每一個容器的數據結構不同,所以取出的動作細節也不一樣。但是都具有共性內容: 判斷和取出。那麼就可以將這些共性抽取。 那麼這些內部類都符合一個規則(或者說都抽取出來一個規則)。該規則就是Iterator。
通過一個對外提供的方法:iterator();,來獲取集合的取出對象。
***迭代器的next方法返回值類型是Object,所以要記得類型轉換。***
*/
public static void method_get()//從容器中取出元素
{
ArrayList<String> a1 = new ArrayList<>();
a1.add("test01");
a1.add("test02");
a1.add("test03");
a1.add("test04");
a1.add("test05");
sop(a1);
for(Iterator<String> iter = a1.iterator();iter.hasNext();)//第一種打印方式,用for循環可以釋放內存。000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000<span id="transmark"></span>
{
System.out.println(iter.next());
}
// Iterator<String> it = a1.iterator();//獲取迭代器,用於取出集合中內容
// while(it.hasNext())//有元素可以迭代,就返回true
// {
// sop(it.next());//輸入迭代器內容,打印下一個元素
// }
}
三、List
Conllection:
List:元素是有序的,且可以重複,因爲該集合存在索引。它獨有的可以修改某個元素。(可以在指定位置插入元素,可以獲取位置,可以根據位置獲取元素等)
--ArrayList:底層的數據結構是使用的是數組結構。特點:查詢比較快,但是增刪比較慢
--LinkedList:底層的數據結構是鏈表結構。特點:增刪比較快,查詢稍慢
--Vector:底層是數組數據結構。比ArrayList早,功能一樣。但是Vector是同步的,ArrayList線程不同步。
Set:元素是無序的,不能重複。
List:
特有方法:凡是可以操作角標的都是該體系特有的方法。
增:
add(index,element);
addAll(index,Collection);
刪:
remove(index);
改:
set(index,element);
查:
get(index);
Iterator;//迭代器;
indexOf(element);//獲取某個元素的位置
subList(from,to);//獲取from至to的元素,包含from,不包含to:[from,to);
listIterator();//列表迭代器,List所特有的
在迭代過程中,準備添加和刪除元素。
List集合特有的迭代器。listIterator()是Iterator()的子接口。
在迭代中,Iterator()的方法是有限的,只有判斷,取出, 刪除,要想有其他操作就必須使用listIterator()。
示例代碼:
for(ListIterator<String> it = a1.listIterator();it.hasNext();)
{
Object obj = it.next();
if(obj.equals("test03"))
{
it.add("test08");//增加一個元素
}
sop("listIterator_obj="+obj);
}
for(ListIterator<String> it = a1.listIterator();it.hasNext();)
{
Object obj = it.next();
sop("listIterator_Obj="+obj);
}
LinkedList特有方法:
示例代碼:
class Stack //堆棧
{
private LinkedList<Object> link;
Stack()
{
link = new LinkedList<>();
}
public void stack_add(Object obj)//堆棧增加元素
{
link.addFirst(obj);
}
public Object stack_Get()//獲取堆棧元素
{
return link.removeFirst();
}
public boolean stack_IsNull()//判斷堆棧是否爲空
{
return link.isEmpty();
}
}
class Queue//隊列
{
private LinkedList<Object> link;
Queue()
{
link = new LinkedList<>();
}
public void queue_add(Object obj)//隊列增加元素
{
link.addFirst(obj);
}
public Object queue_Get()//獲取隊列元素
{
return link.removeLast();
}
public boolean queue_IsNull()//判斷隊列是否爲空
{
return link.isEmpty();
}
}
List練習:
package Container;
import java.util.*;
/*
**將自定義對象作爲元素存到ArrayList集合中,並去除重複元素。
* 比如:存人對象。同名同年齡,視爲同一人,爲重複元素。//注意判斷重複時候要重寫equals()方法,因爲計算機不知道怎麼定義自定義元素是否相等。
* 思路:
* 1.對人描述,數據封裝如對象。
* 2.定義容器,將人存入。
* 3.取出。
*
*
*
******List集合判斷元素是否相同,依據是元素的equals方法。******
*/
class Person//定義人對象
{
private String name;
private int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
public boolean equals(Object obj)//重寫equals方法<span id="transmark"></span>
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"----vs----"+p.name);
return this.name.equals(p.name)&&this.age==p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class ArrayListDemo1 {
public static void sop(Object obj)//打印
{
System.out.println(obj);
}
public static ArrayList<Person> singleElement(ArrayList<Person> al)//去重複元素
{
//定義一個臨時容器
ArrayList<Person> newAl = new ArrayList<>();
for(Iterator<Person> it = al.iterator();it.hasNext();)
{
Person p = it.next();
if(!newAl.contains(p))//必須要重寫equals方法,contains的基礎是equals方法。
newAl.add(p);
}
return newAl;
}
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<>();
al.add(new Person("asla01",12));
al.add(new Person("asla01",12));
al.add(new Person("asla02",22));
al.add(new Person("asla03",15));
al.add(new Person("asla04",31));
al.add(new Person("asla05",21));
al.add(new Person("asla05",21));
al = singleElement(al);
for(Iterator<Person> it = al.iterator();it.hasNext();)
{
Person p = it.next();//如果上面沒有定義Person類型,這裏就必須強行轉換。
sop(p.getName()+"::"+p.getAge());
}
}
}
總結:頻繁的增刪操作採用LinkedList,頻繁的查詢使用ArrayList。一般的情況下都使用ArrayList,因爲它的底層數據結構是數組結構,查詢快。而LinkedList的底層數據結構是鏈表,便於增刪,但是查詢較慢。
四、Hashset
set:元素是無序的,且不能重複。
|--Set:元素無序,且不能重複。
|--HashSet:底層結構是哈希表。
HashSet如何保證元素的唯一性呢?
通過元素的hashCode和equals方法完成。當hashCode值相同時候,纔會判斷equals。
|--TreeSet:
Set集合的功能和Collection是一致的。
具體上代碼:
package Container;
import java.util.HashSet;
import java.util.Iterator;
/*
|--Set:元素無序,且不能重複。
|--HashSet:底層結構是哈希表。
HashSet如何保證元素的唯一性呢?
通過元素的hashCode和equals方法完成。當hashCode值相同時候,纔會判斷equals。
注意:判斷元素是否存在,刪除等操作,都依賴hashCode和equals方法。<span id="transmark"></span>
|--TreeSet:
Set集合的功能和Collection是一致的。
*/
class Person1//定義人對象
{
private String name;
private int age;
Person1(String name, int age)
{
this.name = name;
this.age = age;
}
public boolean equals(Object obj)//重寫equals方法。
{
if(!(obj instanceof Person1))
return false;
Person1 p = (Person1)obj;
System.out.println(this.name+"----vs----"+p.name);
return this.name.equals(p.name)&&this.age==p.age;
}
public int hashCode() //重寫hashCode方法
{
return this.name.hashCode()+this.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class HashSetDemo {
public static void sop(Object obj)//打印
{
System.out.println(obj);
}
public static void main(String[] args) {
HashSet<Person1> hs = new HashSet<>();
hs.add(new Person1("lisa01",21));
hs.add(new Person1("lisa02",21));
hs.add(new Person1("lisa02",21));
hs.add(new Person1("lisa03",21));
hs.add(new Person1("lisa04",21));
for(Iterator<Person1>it = hs.iterator();it.hasNext();)
{
Person1 p = it.next();
sop(p.getName()+"--------"+p.getAge());
}
}
}
五、TreeSet
|--TreeSet:可以對其中元素進行自然排序。排序的時候,主要條件相同時候,要比較次要條件。
底層數據結構是二叉樹。
他的排序方式是compareTo方法。TreeSet的刪除,查找都基於此方法。
TreeSet排序的第一種方式:讓元素具有比較性。需要實現Comparable端口,覆蓋conpareTo方法。
這種方式又叫自然順序或者默認順序。
TreeSet排序的另一種方式是:當元素自身不具備比較性時候,或者具備的比較性不是所需要的。這時候需要讓集合自身具備比較性。
第一種排序方式:
import java.util.Iterator;
import java.util.TreeSet;
class People implements Comparable<Object>//定義人對象,Comparable強制讓學生具有可比較性
{
private String name;
private int age;
People(String name, int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)//重寫compareTo方法
{
if(!(obj instanceof People))
throw new RuntimeException("不是一個人");
People p = (People)obj;
if(this.age > p.age)//判斷大於
return 1;
if(this.age==p.age)//當年齡相同時,比較姓名。
{
return this.name.compareTo(p.name);
}
return -1;//判斷小於
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class TreeSetDemo
{
public static void sop(Object obj)//打印
{
System.out.println(obj);
}
public static void main(String[] args)
{
TreeSet<People> ts = new TreeSet<>();
ts.add(new People("test1",10));
ts.add(new People("test2",20));
ts.add(new People("test3",5));
ts.add(new People("test5",5));
ts.add(new People("test4",7));
for(Iterator<People> it = ts.iterator();it.hasNext();)
{
People p = it.next();
sop(p.getName()+"----"+p.getAge());
}
}
}
第二種比較方式:
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
/*
當元素自身不具備比較性,或者具備的比較性不是所需的,這時候需要讓容器自身具備比較性。
定義一個比較器,將比較器對象作爲參數傳遞給TreeSet集合的構造函數。
兩種比較器都存在時候以比較器爲主
定義一個比較器,實現Comparator端口,覆蓋compareTo方法。
*/
/**************第二種比較方式******************/
class MyCompare implements Comparator<Object>//比較器
{
public int compare(Object o1,Object o2)
{
People1 p1 = (People1)o1;
People1 p2 = (People1)o2;
int num;
num = p1.getName().compareTo(p2.getName());//比較姓名
if(num == 0)//如果姓名相同,比較年齡
{
return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));//將整數封裝,然後調用方法比較
/*if(p1.getAge()>p2.getAge()) return 1;
else if(p1.getAge()==p2.getAge()) return 0;
return -1;*/
}
else
return num;
}
}
class People1 implements Comparable<Object>//定義人對象,Comparable強制讓學生具有可比較性
{
private String name;
private int age;
People1(String name, int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)//重寫compareTo方法
{
if(!(obj instanceof People1))
throw new RuntimeException("不是一個人");
People1 p = (People1)obj;
if(this.age > p.age)//判斷大於
return 1;
if(this.age==p.age)//當年齡相同時,比較姓名。
{
return this.name.compareTo(p.name);
}
return -1;//判斷小於
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class TreeSetDemo2
{
public static void sop(Object obj)//打印
{
System.out.println(obj);
}
public static void main(String[] args)
{
TreeSet<People1> ts = new TreeSet<>(new MyCompare());//傳入比較器
ts.add(new People1("Zhangsan",10));
ts.add(new People1("Lisi",20));
ts.add(new People1("Wangwu",5));
ts.add(new People1("Zhangsan",5));
ts.add(new People1("Lilei",7));
for(Iterator<People1> it = ts.iterator();it.hasNext();)
{
People1 p = it.next();
sop(p.getName()+"----"+p.getAge());
}
}
}