1.Collection 接口與集合操作方法
/** * java.util.Collection 接口 * 集合框架 * 集合是用來保存一組元素的,不同的實現類實現了不同數據結構。 * Collection是所有集合的頂級接口,規定了所有集合都必須具備的功能。 * * 集合與數組一樣,保存一組元素,但是操作元素的方法集合已經提供了。 * * Collection下面有兩個常見的子接口(分類) * java.util.List:線性表,特點是可以存放重復元素,並且有序。 * java.util.Set:不可以重復的集合,大部分實現類是無序的。 * * 是否為重復元素是根據元素自身equals比較的結果判定的。 */ public class CollectionDemo { public static void main(String[] args) { Collection c = new ArrayList(); /* * boolean add(E e) * 向集合中添加元素 * 若成功添加則返回值為true。 */ c.add("one"); c.add("two"); c.add("three"); c.add("four"); c.add("five"); System.out.println(c); /* * int size() * 返回當前集合的元素個數 */ int size = c.size(); System.out.println("size:"+size); /* * boolean isEmpty() * 判斷當前集合是否為空集 */ boolean isEmpty = c.isEmpty(); System.out.println("是否為空集:"+isEmpty); /* * 清空集合 */ c.clear(); System.out.println("集合以清空"); System.out.println(c); System.out.println("size:"+c.size()); System.out.println("是否為空集:"+c.isEmpty()); } }
/** * 集合存放元素的引用 */ public class CollectionDemo2 { public static void main(String[] args) { Point p = new Point(1,2); Collection c = new ArrayList(); c.add(p); System.out.println("p:"+p);//(1,2) System.out.println("c:"+c);//[(1,2)] p.setX(2); System.out.println("p:"+p);//(2,2) System.out.println("c:"+c);//[(2,2)] } }
/** * 集合操作 */ public class CollectionDemo3 { public static void main(String[] args) { Collection c1 = new ArrayList(); c1.add("java"); c1.add("c++"); c1.add("c"); System.out.println("c1:"+c1); Collection c2 = new ArrayList(); c2.add("php"); c2.add(".net"); c2.add("java"); System.out.println("c2:"+c2); /* * boolean addAll(Collection c) * 將給定集合中的所有元素添加到當前集合當調用后當前集合元素發生改變則返回true */ c1.addAll(c2); System.out.println("c1:"+c1); Collection c3 = new ArrayList(); c3.add("c++"); c3.add("php"); // c3.add("ios"); System.out.println("c3:"+c3); /* * 判斷當前集合是否包含給定集合中的所有元素。 */ boolean contains = c1.containsAll(c3); System.out.println("全包含:"+contains); /* * 刪除當前集合中與給定集合的共有元素 * 給定的集合元素不發生變化。 */ c1.removeAll(c3); System.out.println("c1:"+c1); System.out.println("c3:"+c3); } }
/** * boolean contains(Object o) * 判斷集合是否包含給定元素 */ public class ContainsDemo { public static void main(String[] args) { Collection c = new ArrayList(); c.add(new Point(1,2)); c.add(new Point(3,4)); c.add(new Point(5,6)); c.add(new Point(7,8)); System.out.println(c); Point p = new Point(1,2); /* * contains的判斷依據是用給定的元素與集合每一個元素進行equals比較,只要有為true的,就認為包含。 * 因此元素的equals方法直接影響contains的判斷結果。 */ boolean contains = c.contains(p); System.out.println("是否包含:"+contains); } }
2.泛型
/** * 泛型是JDK5之后推出的一個特性,又稱為參數化類型,允許我們在使用一個類時指定它的屬性, * 方法的參數和返回值的類型,使得我們使用起來更靈活。 * 泛型的原型是Object,不指定時就使用它。 * 泛型在集合中廣泛使用,用於規定集合中的元素類型 */ public class CollectionDemo4 { public static void main(String[] args) { //規定當前集合元素為String Collection<String> c = new ArrayList<String>(); //添加元素時只能傳入String類型元素 c.add("one"); c.add("two"); c.add("three"); c.add("four"); System.out.println(c); //遍歷時可以直接用String類型接收元素 for(String str : c) { System.out.println(str); } /* * 迭代器的泛型與其遍歷的集合指定的泛型一致即可。 */ Iterator<String> it = c.iterator(); while(it.hasNext()) { String str = it.next(); System.out.println(str); } } }
3.基本數據類型與引用數據類型的區別
public class Demo { public static void main(String[] args) { int a = 1; String s = "hello"; Point p = new Point(1,2); Collection c = new ArrayList(); c.add(p); test(a,s,p,c); System.out.println("a:"+a);//1 System.out.println("s:"+s);//hello System.out.println("p:"+p);//(2,2) System.out.println("c:"+c);//[(2,6)] } public static void test(int a,String s,Point p,Collection c) { a++; s = s+"world"; p.setX(2); p = new Point(5,6); c.clear(); c.add(p); p.setX(a); c = new ArrayList(); c.add(new Point(7,8)); } }
4.迭代器 Iterator
/** * 遍歷集合 * 集合提供了統一的遍歷操作,無論哪種數據結構實現的集合都提供了該遍歷方式:迭代器模式 * * Iterator iterator() * Collection提供的iterator方法可以獲取一個用於遍歷當前集合的迭代器 * * java.util.Iterator接口 * 該接口是迭代器接口,規定了遍歷集合的相關操作所有集合都有一個用於遍歷自身的迭代器實現類, * 我們無需關注它們的類名,以多態的角度用該接口看待並調用相關遍歷方法即可。 * * 使用迭代器遍歷集合的統一方式遵循為: * 問->取->刪 * 其中刪除元素不是必須操作 */ public class IteratorDemo { public static void main(String[] args) { Collection c = new ArrayList(); c.add("one"); c.add("#"); c.add("two"); c.add("#"); c.add("three"); c.add("#"); c.add("four"); c.add("#"); c.add("five"); System.out.println(c); Iterator it = c.iterator(); /* * 問 * boolean hasNext() * 通過迭代器查看是否還有元素可以遍歷 */ while(it.hasNext()) { /* * 取 * E next() * 通過迭代器遍歷下一個元素 */ String str = (String)it.next(); System.out.println(str); if("#".equals(str)) { /* * 迭代器有一個要求,就是遍歷的過程中不能通過集合的方法 * 增刪元素。否則遍歷時會拋出異常 */ // c.remove(str); /* * 迭代器提供了remove方法,該方法不需要傳入參數,刪除 * 的就是本次遍歷通過next獲取的元素 */ it.remove(); } } System.out.println(c); } }
5.增強for循環
/** * JDK5之后推出了一個特性:增強型for循環 * 也稱為新循環,它不取代傳統for循環的工作,僅用來遍歷集合或數組使用 */ public class NewForDemo1 { public static void main(String[] args) { String[] array = {"one","two","three","four"}; for(int i=0;i<array.length;i++) { String str = array[i]; System.out.println(str); } /* * 新循環是編譯器認可,而不是虛擬機,編譯器在編譯源代碼時會將新循環遍歷 * 數組改為傳統for循環遍歷。 */ for(String str:array) { System.out.println(str); } } }
/** * 使用新循環遍歷集合 */ public class NewForDemo2 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("one"); c.add("two"); c.add("three"); c.add("four"); /* * 使用新循環遍歷集合會被編譯器編譯時改為使用迭代器遍歷,因此要遵循迭代器 * 使用規范,遍歷過程中不能通過集合的方法增刪元素 */ for(Object o : c) { String str = (String)o; System.out.println(str); if("#".equals(str)) { c.remove(str); } } System.out.println(c); } }
6.List 線性表
/** * java.util.List 線性表 * List集合是有個可以重復的集合,並且有序,特點是提供了一組通過下標操作元素的方法。 * * 常用實現類: * java.util.ArrayList * 內部使用數組實現,查詢性能更好,但是增刪元素性能差 * * java.util.LinkedList * 內部使用鏈表實現,增刪元素性能好,尤其首尾 * 增刪元素性能最佳,但是查詢性能差 * * 如果對性能沒有特別苛刻的要求時,通常使用ArrayList即可。 */ public class ListDemo1 { public static void main(String[] args) { /* * JDK7之后,右側的<>指定泛型部分可以不再寫具體的類型了,編譯器會理解為 * 與前面指定的一致。 */ List<String> list = new ArrayList<>(); list.add("one"); list.add("two"); list.add("three"); list.add("four"); list.add("five"); System.out.println(list); /* * E get(int index) * 獲取給定下標處對應的元素 */ String str = list.get(1); System.out.println(str); //傳統for循環可以遍歷List集合 for(int i=0;i<list.size();i++) { str = list.get(i); System.out.println(str); } /* * E set(int index,E e) * 將給定元素設置到指定位置上,返回值為原位置對應的元素。 * 所以set是替換元素操作 */ //[one,2,three,four,five] String old = list.set(1, "2"); System.out.println(list); System.out.println("old:"+old); /* * 在不創建新集合的前提下,將list集合元素顛倒位置 * [five,2,three,four,one] * [five,four,three,2,one] */ for(int i=0;i<list.size()/2;i++) { //獲取正數位置的元素 str = list.get(i); //設置到倒數位置並獲取替換的元素 old = list.set(list.size()-1-i, str); //將替換的元素設置到正數位置完成交換 list.set(i, old); // list.set(i, list.set(list.size()-1-i, list.get(i))); } System.out.println(list); } }
/** * List提供了一對重載的add,remove方法 */ public class ListDemo2 { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("one"); list.add("two"); list.add("three"); list.add("four"); list.add("five"); System.out.println(list); /* * void add(int index,E e) * 將給定元素插入到指定位置 */ list.add(2,"2"); System.out.println(list); /* * E remove(int index) * 刪除並返回給定位置上的元素 */ String old = list.remove(1); System.out.println(list); System.out.println(old); } }
/** * List subList(int start,int end) * 獲取當前集合中指定范圍的子集 */ public class ListDemo3 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for(int i=0;i<10;i++) { list.add(i); } System.out.println(list); List<Integer> subList = list.subList(3, 8); System.out.println(subList); //將子集元素擴大10倍 for(int i=0;i<subList.size();i++) { int num = subList.get(i); num = num*10; subList.set(i, num); } System.out.println(subList); /* * 修改子集元素就是修改原集合對應元素 */ System.out.println(list); //刪除2-8 list.subList(2, 9).clear(); System.out.println(list); } }
7.集合與數組的相互轉換 toArray asList
/** * Collection中定義了一個方法toArray * 可以將當前集合轉換為數組 */ public class CollectionToArrayDemo { public static void main(String[] args) { Collection<String> c = new ArrayList<>(); c.add("one"); c.add("two"); c.add("three"); c.add("four"); System.out.println(c); // Object[] array = c.toArray(); String[] array = c.toArray(new String[c.size()]); System.out.println(array.length); System.out.println(Arrays.toString(array)); } }
/** * 數組轉換為List集合 * 數組的工具類Arrays提供了一個靜態方法asList * 可以將給定的數組轉換為一個List集合 */ public class ArrayToListDemo { public static void main(String[] args) { String[] array = {"one","two","three","four"}; List<String> list = Arrays.asList(array); System.out.println(list.size()); System.out.println(list); /* * 對數組轉換而來的集合的元素操作就是對原數組對應元素的操作。 */ list.set(1, "2"); System.out.println(list); System.out.println(Arrays.toString(array)); /* * 由於數組的定長的,因此會改變數組元素個數的操作都是不支持的,會拋出異常 */ // list.add("five"); /* * 若希望對集合元素增刪操作,可以另外創建一個集合 * * 所有的集合都支持一個參數為Collection類型的構造方法,作用是創建該集合的同 * 時包含給定集合中的所有元素 */ List<String> list2 = new ArrayList<>(list); list2.add("five"); System.out.println(list2); } }
8.集合的排序
/** * List集合的排序 */ public class SortListDemo { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); Random random = new Random(); for(int i=0;i<10;i++) { list.add(random.nextInt(100)); } System.out.println(list); Collections.sort(list); System.out.println(list); } }
public class SortListDemo2 { public static void main(String[] args) { /* * 對一組人進行自定義排序 * 課后任務:實現對一組連衣裙進行自定義排序按照價格排序,尺碼排序 */ List<Person> list=new ArrayList<>(); list.add(new Person("熊大",3,200)); list.add(new Person("熊二",2,220)); list.add(new Person("光頭強",30,120)); list.add(new Person("范傳奇",35,300)); //自定義排序必須提供比較器! //Collections.sort(list, 比較器); Collections.sort(list, new ByAge()); System.out.println(list); Collections.sort(list, new ByWeight()); System.out.println(list); /* * 使用匿名內部類實現排序 */ //利用匿名內部類聲明按照年齡比較 Comparator<Person> byAge= new Comparator<Person>(){ public int compare(Person o1, Person o2) { return o1.age-o2.age; } }; Collections.sort(list, byAge); System.out.println(list); //最終版本, 最簡潔版本 Collections.sort(list, new Comparator<Person>(){ public int compare( Person o1, Person o2) { return -(o1.age-o2.age); } }); System.out.println(list); //最終版本: 按照重量比較 Collections.sort(list, new Comparator<Person>() { public int compare(Person o1, Person o2) { return -(int)Math.signum(o1.weight-o2.weight); } }); System.out.println(list); } } class ByWeight implements Comparator<Person>{ public int compare(Person o1, Person o2) { return -(int)Math.signum(o1.weight-o2.weight); } //符號函數 public int sgn(double d){ if(d==0) { return 0; }else if(d<0){ return -1; }else { return 1; } } } /* * 實現按照人的年齡比較大小的比較器 * age 年齡 * Comparator 比較器 * Person 人 */ class ByAge implements Comparator<Person>{ public int compare(Person o1, Person o2) { //按照兩個人的年齡比較 //o1 代表某人1, o2代表某人2 return -(o1.age - o2.age); } } class Person{ String name; int age; double weight; public Person(String name, int age, double weight) { this.name = name; this.age = age; this.weight = weight; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", weight=" + weight + "]"; } }
public class SortListDemo3 { public static void main(String[] args) { /* * 字符串大小比較問題 * 字符串提供了比較函數,其規則是按照字符中的字符編碼進行比較 * 返回0 表示兩個字符串相等返回正數表示第一個字符串大 * 返回負數表示第一個字符串小 */ int code1 = '熊'; int code2 = '光'; int code3 = '范'; System.out.println(code1); System.out.println(code2); System.out.println(code3); String s1 = "熊大"; //29066 String s2 = "光頭強";//20809 //字符串提供比較大小方法, //比較兩個字符串時候,返回0表示相等返回正數表示第一個字符串大 //返回負數表示第一個字符串小 int n = s1.compareTo(s1); System.out.println(n); //0 相等 n = s1.compareTo(s2); System.out.println(n); //正數,s1大 n = s2.compareTo(s1); System.out.println(n); //負數,s2小 List<Person> list=new ArrayList<>(); list.add(new Person("范傳奇",1,2)); list.add(new Person("熊大",3,5)); list.add(new Person("熊二",4,9)); list.add(new Person("光頭強",7,9)); list.add(new Person("李大嘴",8,8)); Collections.sort(list, new Comparator<Person>() { public int compare( Person o1, Person o2) { //利用字符串提供的方法,按照名字比較大小 return o1.name.compareTo(o2.name); } }); System.out.println(list); } }