對象數組
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
public class Main {
public static void main(String[] args) {
Student[] Students = new Student[5];
Student s = new Student("張飛", 25);
Student s2 = new Student("關羽", 28);
Student s3 = new Student("趙雲", 25);
Student s4 = new Student("黃忠", 30);
Student s5 = new Student("馬超", 25);
Students[0] = s;
Students[1] = s2;
Students[2] = s3;
Students[3] = s4;
Students[4] = s5;
for (int i = 0; i < Students.length; i++) {
System.out.println(Students[i].getName()+"---"+Students[i].getAge());
}
}
}
---------------------------------------------------------------------------
張飛---25
關羽---28
趙雲---25
黃忠---30
馬超---25
集合的由來:
爲了方便對多個對象進行操作,必須對多個對象進行存儲。多個對象進行存儲可以選擇對象數組;因數組長度是固定的,對象數組不能適應變化的需求,爲了適應變化的需求,Java提供集合類。
數組和集合的區別
A、長度區別
數組的長度固定
集合的長度可變
B、內容不同
數組存儲的是同一種類型的元素
而集合可以存儲不同類型的元素
C、元素的數據類型問題
數組可以存儲基本數據類型,也可以存儲引用數據類型
集合只能存儲引用類型
集合類特點
集合只能用於存儲對象,集合長度是可變的,集合可以存儲不同類型的對象。
Collection:是集合的頂層接口,它的子體系有重複的,有唯一的,有有序的,有無序的。
Collection的功能概述:
1、添加功能
boolean add(Object obj):添加一個元素(通過ArrayList類進行實例話,永遠返回true,永遠添加成功即允許有重複的)
boolean addAll(Collection c):添加一個集合的元素(類似於add(Object obj)方法)
2、刪除功能
void clear():移除所有元素
boolean remove(Object o):移除一個元素
boolean removeAll(Collection c): 移除一個集合的元素(只要有一個被移除,就返回true,即移除成功)
3、修改功能
boolean contains(Object o):判斷集合中是否包含指定的元素
boolean containsAll(Collection c):判斷集合中是否包含指定的集合元素(只有包含集合中所有的元素纔是包含,否則爲false)
boolean isEmpty(): 判斷集合是否爲空
4、獲取功能
Iterator iterator():迭代器,集合的專用遍歷方式
Iterator接口中方法:
Object next():獲取元素,並移動到下一位置。
boolean hasNext():如果仍有元素可以迭代,則返回true。
5、長度功能
int size():元素的個數
6、交集功能
boolean retainAll(Collection c):(集合A對集合B做交集,最終結果保存在A中,B不變。返回值表示爲A是否發生過改變,true爲A發生改變,false爲不改變)
7、把集合轉換爲數組
Object[] toArray()
import java.util.ArrayList;
import java.util.Collection;
public class Main {
public static void main(String[] args) {
//創建集合對象
Collection c = new ArrayList();
Student[] Students = new Student[5];
Student s = new Student("張飛", 25);
Student s2 = new Student("關羽", 28);
Student s3 = new Student("趙雲", 25);
Student s4 = new Student("黃忠", 30);
Student s5 = new Student("馬超", 25);
//把學生添加到集合
c.add(s);
c.add(s2);
c.add(s3);
c.add(s4);
c.add(s5);
//把集合轉成數組
Object[] objt = c.toArray();
for(int i = 0;i<objt.length;i++) {
Student ss = (Student) objt[i];
System.out.println(ss.getName()+"---"+ss.getAge());
}
}
}
---------------------------------------------------------------------------------------------
張飛---25
關羽---28
趙雲---25
黃忠---30
馬超---25
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorDemo {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
Iterator it = c.iterator();
while(it.hasNext()) {
String s = (String) it.next();
System.out.println(s+"----"+s.length());
}
}
}
-----------------------------------------------------------------------------------
hello----5
world----5
java----4
集合的使用步驟:
A:創建集合對象
B:創建元素對象
C:把元素添加到集合
D:遍歷集合
a:通過集合對象獲取迭代器對象
b:通過迭代器對象的hasNext()方法判斷是否有元素
c:通過迭代器對象的next()方法獲取元素並移動到下一位置
迭代器爲什麼不定義爲一個類,而是一個接口?
由於Java中提供了很多的集合類,而這些集合類的數據方法不同,所以存儲的方式和遍歷的方式應該也不同,進而它們的遍歷方式也應該不一樣。最終沒有定義迭代器類。集合都應該具備獲取元素的操作,判斷功能和獲取功能應該是一個集合遍歷所具備的,而每種集合的方式不同。所以把這兩個功能提取出來並不提供實現,這種方式就是接口。
真正的具體實現類在哪裏?
在真正的具體的子類中,以內部類的方式體現的。
迭代器源碼:
public interface Iterator<E> {
boolean hasNext();
E next();
}
public interface Iterable<T> {
Iterator<T> iterator();
}
public interface Collection<E> extends Iterable<E> {
Iterator<E> iterator();
}
public interface List<E> extends Collection<E> {
Iterator<E> iterator();
}
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
public boolean hasNext() {}
public E next() {}
}
}
List接口概述
有序的Collection(也稱爲序列)。此接口的用戶可以對列表中的每個元素的插入位置進行精確地控制。用戶可以根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素。(與set不同,列表通常允許重複的元素。)
List集合的特有功能:
A:添加功能
void add(int index, Object element):在指定位置添加元素
B:獲取功能
Object get(int index):獲取指定位置的元素
List集合的特有遍歷功能:
size()和get()方法結合。
C:列表迭代器
ListIterator listIterator():List集合特有的迭代器
該迭代器繼承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法。
特有功能:
Object previous():獲取上一個元素
boolean hasPrevious():判斷是否有元素
注意:ListIterator可以實現逆向遍歷,但是必須先正向遍歷,才能逆向遍歷,所以一般無意義,不使用。
D:刪除功能
Object remove(int index):根據索引刪除元素,返回被刪除的元素
E:修改功能
Object set(int index, Object element):根據索引修改元素,返回被修改的元素
問題:判斷集合中是否有"world"元素,若有,添加"javaee"元素。
ConcurrentModificationException:當方法檢測到對象的併發修改,但不允許這種修改時,拋出此異常。
產生原因:
迭代器是依賴於集合而存在的,在判斷成功後,集合中新添加了元素,而迭代器卻不知道,所以報錯,這種錯誤叫併發修改異常。
問題描述爲:迭代器遍歷元素的時候,通過集合是不能修改元素的。
解決方法:
A:迭代器迭代元素,迭代器修改元素
新加元素是跟在剛纔判斷迭代的元素後面。
B:集合遍歷元素,集合修改元素(普通for)
新加元素在集合最後添加
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class IteratorDemo2 {
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
//迭代器遍歷
//報錯:ConcurrentModificationException
// Iterator it = list.iterator();
// while(it.hasNext()) {
// String s = (String) it.next();
// if("world".equals(s)) {
// list.add("javaee");
// }
// }
//方式A:迭代器迭代元素,迭代器修改元素
//而Iterator迭代器卻沒有添加功能,所以我們使用其子接口ListIterator
// ListIterator lit = list.listIterator();
// while (lit.hasNext()) {
// String s = (String) lit.next();
// if ("world".equals(s)) {
// lit.add("javaee");
// }
// }
// System.out.println("list:"+list);
//list:[hello, world, javaee, java]
//方式B:集合遍歷元素,集合修改元素(普通for)
for(int x=0;x<list.size();x++) {
String s = (String) list.get(x);
if("world".equals(s)) {
list.add("javaee");
}
}
System.out.println("list:"+list);
//list:[hello, world, java, javaee]
}
}
List的子類特點:
ArrayList:
底層數據結構是數組,查詢快,增刪慢。
線程不安全,效率高。
Vector:
底層數據結構是數組,查詢快,增刪慢。
線程安全,效率低。
LinkedList:
底層數據結構是鏈表,查詢慢,增刪快。
線程不安全,效率高。
去除集合中重複的字符串的重複值兩種方法:
import java.util.ArrayList;
import java.util.Iterator;
//去除集合中重複的字符串的重複值
public class ArrayListDemo {
public static void main(String[] args) {
//創建集合對象
ArrayList array = new ArrayList();
//添加多個字符串元素(包含內容相同的)
array.add("hello");
array.add("world");
array.add("java");
array.add("world");
array.add("java");
array.add("world");
array.add("java");
array.add("java");
array.add("java");
array.add("world");
array.add("world");
array.add("java");
array.add("java");
//方法1:創建新集合,遍歷舊集合新集合中沒有的加入到舊集合中
ArrayList newarray = new ArrayList();
Iterator it = array.iterator();
while(it.hasNext()) {
String s = (String) it.next();
if(!newarray.contains(s)) {
newarray.add(s);
}
}
//遍歷新集合
for(int i=0; i<newarray.size(); i++) {
String s= (String) newarray.get(i);
System.out.println(s);
}
// hello
// world
// java
//方法2:雙重循環在原集合中去除重複元素
for(int i=1; i<array.size(); i++) {
for(int j=0; j<i;j++) {
if(array.get(i).equals(array.get(j))) {
array.remove(i);
i--;
break;
}
}
}
for(int i=0; i<array.size(); i++) {
String s= (String) array.get(i);
System.out.println(s);
}
// hello
// world
// java
}
}
注意:contains()方法的底層依賴的是equals()方法。所以Student類重寫equals()方法。
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo2 {
public static void main(String[] args) {
// 創建集合對象
ArrayList array = new ArrayList();
// 創建學生對象
Student s1 = new Student("關羽", 25);
Student s2 = new Student("張飛", 27);
Student s3 = new Student("趙雲", 24);
Student s4 = new Student("馬超", 26);
Student s5 = new Student("黃忠", 30);
Student s6 = new Student("趙雲", 22);
Student s7 = new Student("馬超", 26);
Student s8 = new Student("黃忠", 30);
Student s9 = new Student("關羽", 28);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
array.add(s5);
array.add(s6);
array.add(s7);
array.add(s8);
array.add(s9);
//創建新集合
ArrayList newArray = new ArrayList();
//遍歷舊集合,獲取得到每一個元素
Iterator it = array.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
if(!newArray.contains(s)) {
newArray.add(s);
}
}
//遍歷新集合
for(int x = 0; x< newArray.size();x++) {
Student s = (Student) newArray.get(x);
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
-----------------------------------------------------------------
關羽---25
張飛---27
趙雲---24
馬超---26
黃忠---30
趙雲---22
關羽---28
泛型:是一種把類型明確的工作推遲到創建對象或者調用方法的時候纔去明確的特殊的類型。參數化類型,把類型當作參數一樣的傳遞。
格式:
<數據類型>
此處的數據類型只能是引用類型。
好處:
A:把運行時期的問題提前到了編譯期間
B:避免了強制類型轉換
C:優化了程序設計,解決了黃色警告線
泛型使用位置:
看API,如果類,接口,抽象類後面跟的有<E>就說要使用泛型。一般來說就是在集合中使用。
泛型由來
早期的Object類型可以接收任意的對象類型,但是在實際的使用中,會有類型的轉換的問題。也就存在着隱患,所以Java提供了泛型來解決這個安全問題。
泛型應用
泛型類
把泛型定義在類上
格式:public class 類名<泛型類型1,泛型類型2,....>
注意:泛型類型必須是引用類型
泛型方法
把泛型定義在方法上
格式:public <泛型類型> 返回類型 方法名(泛型類型)
泛型接口
把泛型定義在接口上
格式:public interface 接口名<泛型類型1,....>
泛型高級(通配符)
泛型通配符<?>
任意類型,如果沒有明確,那麼就是Object以及任意的Java類了
? extends E
向下限定,E及其子類
? super E
向上限定,E及其父類
import java.util.ArrayList;
import java.util.Iterator;
//去除集合中重複的字符串的重複值
public class ArrayListDemo {
public static void main(String[] args) {
// 創建集合對象
ArrayList<String> array = new ArrayList<String>();
// 添加多個字符串元素(包含內容相同的)
array.add("hello");
array.add("world");
array.add("java");
array.add("world");
array.add("java");
array.add("world");
array.add("java");
array.add("java");
array.add("java");
array.add("world");
array.add("world");
array.add("java");
array.add("java");
// 方法1:創建新集合,遍歷舊集合新集合中沒有的加入到舊集合中
ArrayList<String> newarray = new ArrayList<String>();
Iterator<String> it = array.iterator();
while (it.hasNext()) {
String s = it.next();
if (!newarray.contains(s)) {
newarray.add(s);
}
}
// 遍歷新集合
for (int i = 0; i < newarray.size(); i++) {
String s = newarray.get(i);
System.out.println(s);
}
// hello
// world
// java
// 方法2:雙重循環在原集合中去除重複元素
for (int i = 1; i < array.size(); i++) {
for (int j = 0; j < i; j++) {
if (array.get(i).equals(array.get(j))) {
array.remove(i);
i--;
break;
}
}
}
for (int i = 0; i < array.size(); i++) {
String s = array.get(i);
System.out.println(s);
}
// hello
// world
// java
}
}
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo2 {
public static void main(String[] args) {
// 創建集合對象
ArrayList<Student> array = new ArrayList<Student>();
// 創建學生對象
Student s1 = new Student("關羽", 25);
Student s2 = new Student("張飛", 27);
Student s3 = new Student("趙雲", 24);
Student s4 = new Student("馬超", 26);
Student s5 = new Student("黃忠", 30);
Student s6 = new Student("趙雲", 22);
Student s7 = new Student("馬超", 26);
Student s8 = new Student("黃忠", 30);
Student s9 = new Student("關羽", 28);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
array.add(s5);
array.add(s6);
array.add(s7);
array.add(s8);
array.add(s9);
//創建新集合
ArrayList<Student> newArray = new ArrayList<Student>();
//遍歷舊集合,獲取得到每一個元素
Iterator<Student> it = array.iterator();
while (it.hasNext()) {
Student s = it.next();
if(!newArray.contains(s)) {
newArray.add(s);
}
}
//遍歷新集合
for(int x = 0; x< newArray.size();x++) {
Student s = (Student) newArray.get(x);
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
增強for:是for循環的一種
格式:
for(元素數據類型 變量:數組或者Collection集合){
使用變量即可,該變量就是元素
}
嵌套集合
import java.util.ArrayList;
public class ArrayListDemo3 {
public static void main(String[] args) {
// 創建班級集合
ArrayList<ArrayList<Student>> bigArrayList = new ArrayList<ArrayList<Student>>();
// 創建第一個學生集合
ArrayList<Student> firstArrayList = new ArrayList<Student>();
// 創建學生對象
Student s1 = new Student("唐僧", 30);
Student s2 = new Student("孫悟空", 29);
Student s3 = new Student("豬八戒", 28);
Student s4 = new Student("沙僧", 27);
Student s5 = new Student("白龍馬", 26);
firstArrayList.add(s1);
firstArrayList.add(s2);
firstArrayList.add(s3);
firstArrayList.add(s4);
firstArrayList.add(s5);
bigArrayList.add(firstArrayList);
// 創建第二個學生集合
ArrayList<Student> secondArrayList = new ArrayList<Student>();
// 創建學生對象
Student s11 = new Student("諸葛亮", 30);
Student s22 = new Student("司馬懿", 28);
Student s33 = new Student("周瑜", 26);
secondArrayList.add(s11);
secondArrayList.add(s22);
secondArrayList.add(s33);
bigArrayList.add(secondArrayList);
// 創建第二個學生集合
ArrayList<Student> thirdArrayList = new ArrayList<Student>();
// 創建學生對象
Student s111 = new Student("宋江", 40);
Student s222 = new Student("吳用", 35);
Student s333 = new Student("高俅", 30);
Student s444 = new Student("李師師", 22);
thirdArrayList.add(s111);
thirdArrayList.add(s222);
thirdArrayList.add(s333);
thirdArrayList.add(s444);
bigArrayList.add(thirdArrayList);
//遍歷
for(ArrayList<Student> array : bigArrayList) {
for(Student s : array) {
System.out.println(s.getName()+"---"+s.getAge());
}
System.out.println("----------------");
}
}
}
----------------------------------------------------------------------------------------------
唐僧---30
孫悟空---29
豬八戒---28
沙僧---27
白龍馬---26
----------------
諸葛亮---30
司馬懿---28
周瑜---26
----------------
宋江---40
吳用---35
高俅---30
李師師---22
----------------
可變參數概述:
定義方法的時候不知道該定義多少個參數
格式:
修飾符 返回值類型 方法名(數據類型... 變量名){}
注意:
這裏的變量其實是一個數組
如果一個方法有可變參數,並且有多個參數,那麼,可變參數肯定是最後一個
Arrays工具類中的一個方法
public static <T> List<T> asList(T... a)