第十章 Collection集合框架
常用方法:
c.add( E e);//向集合中追加元素
c.size();//集合中元素的个数
c.isEmpty();//判断集合中是否有元素,无元素返回true
c.isContains(Object o);//判断几个中是否包含给定元素
c.clear();//清空集合,使集合中无元素,size()=0,isEmpty()为true
c.remove(Object other);//将给定元素从当前集合中删除
c.addAll(c1);//将集合c1中的元素添加到c集合中
c.removeAll(c1);//删除c1集合和当前集合共有的元素
c.containsAll(c1);//判断集合c是否完全包含给定的c1集合中的元素
Iterator it = c.iterator();//创建一个迭代器
it.hasNext();//判断是否有下一个元素
String str = (String)it.next();//获取下一个元素
it.remove();//迭代器提供的删除方法,一次只能删除一个元素
for each//jdk5后推出的新特性,新循环,冒号后是数组或集合,冒号前是声明接收元素的变量
Type<String>//泛型,也称为参数化类型,引用类时允许传入指定类型来约束类中(某个属性,方法的参数,方法的返回值)的类型,提高代码的灵活性,长用于约束集合中元素的类型;
* java.util.Collection 集合框架
* 集合与数组相似,都用来存放一组元素。但是集合提供了操作元素的相关方法,使用更方便;
* 并且集合含有多种不同的实现结构,将来结合实际需求选择合适的实现类来存放元素;
*集合存放的是元素的引用
1 public class CollectionDemo { 2 public static void main(String[] args) { 3 /* 4 * Collection接口下面有两个常用的派生接口“ 5 * java.util.List; 线性表,特点:可重复,有序。即相同元素可以重复放入集合; 6 * java.util.Set; 元素不可重复;默认无序,但是有有序的实现方法; 7 * 元素是否重复依靠的是元素自身equals比较的结果; 8 */ 9 Collection c = new ArrayList(); 10 /* 11 * boolean型方法:add(E,e); 12 * 向当前集合中添加给定元素,若成功添加则返回true,反之则false; 13 * (E,e)先理解为object 14 */ 15 c.add("one"); 16 c.add("two"); 17 c.add("three"); 18 c.add("four"); 19 c.add("one"); 20 System.out.println("ArrayList:"+c);//ArrayList:[one, two, three, four, one] 21 int size = c.size(); 22 //size是指集合中元素的个数 23 //size和数组中的length不是一个概念,length是数组在创建时声明的元素个数,不能随便添加超过length的元素,集合则不限制 24 System.out.println("size:"+size);//size:5 25 26 //判断当前集合是否为空集。空集是指集合不含任何元素,与null意义不同,null意味着没有集合,空集指有集合,但集合中无元素 27 boolean isEmpty = c.isEmpty(); 28 System.out.println("空集:"+isEmpty);//空集:false 29 30 //void clear(); 清空集合 31 c.clear(); 32 System.out.println("集合已清空!"); 33 System.out.println("size:"+c.size());//0 34 System.out.println("空集:"+c.isEmpty());//true 35 System.out.println(c);//[] 36 37 // Collection d = new HashSet();//元素不可重复;默认无序,但是有有序的实现方法; 38 // d.add("one"); 39 // d.add("two"); 40 // d.add("three"); 41 // d.add("four"); 42 // d.add("one"); 43 // System.out.println("HashSet:"+d);//HashSet:[four, one, two, three] 44 } 45 } 46 47 * boolean 型,remove(Object other); 48 * 将给定元素从当前集合中删除; 49 * 删除的标准是集合会顺序将给定元素与集合现有元素进行equals比较并删除比较结果为true的元素; 50 * (若集合中存在重复元素,只删除一个,即调用一次remove方法,只删除一个元素) 51 boolean remove = c.remove(p); 52 53 * boolean 型,contains(Object o) 54 * 判断当前集合是否包含给定的元素 55 Point p = new Point(1,2); 56 boolean contains = c.contains(p); 57 System.out.println("包含:"+contains); 58 59 60 Collection c = new ArrayList(); 61 c.add("java"); 62 c.add("android"); 63 c.add("ios"); 64 System.out.println("c: "+c); 65 //c: [java, android, ios] 66 Collection c1 = new HashSet(); 67 c1.add("c"); 68 c1.add("c++"); 69 c1.add("c#"); 70 c1.add("java"); 71 System.out.println("c1:"+c1); 72 //c1:[c#, c++, c, java] 73 * boolean型,addAll(Collection c) 74 * 将给定集合元素存入当前集合中 75 c.addAll(c1); 76 System.out.println("c: "+c); 77 //c: [java, android, ios, c#, c++, c, java] 78 c1.addAll(c); 79 System.out.println("c1:"+c1); 80 //c1:[c#, c++, c, java, android, ios] 81 82 Collection c2 = new ArrayList(); 83 c2.add("java"); 84 c2.add("php"); 85 c2.add("python"); 86 c.removeAll(c2);//删除当前集合中与给定集合共有的元素 87 //c: [android, ios, c#, c++, c] 88 89 90 boolean containsAll = c.containsAll(c1); 91 //判断当前集合是否完全包含给定集合元素; 92 System.out.println("c是否包含c1:"+containsAll);
【遍历集合】
package collection; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * 集合提供了统一的获取元素的方式:遍历集合 * 而集合遍历采取的是迭代器模式 * 集合定义了方法: * Iterator iterator() * 该方法可以获取一个用于遍历当前集合的迭代器 * * java.util.Iterater接口 * 该接口规定了迭代器遍历集合的相关方法,不同的集合都实现了一个迭代器的实现类用于遍历自身元素 * 我们无需记住每个迭代器实现类的名字,只要以多态角度当作Iterator看待,并调用相关方法遍历集合元素即可 * * 迭代器遍历集合遵循步骤:问,取,删 * 其中删除元素不是必须操作; */ public class IteratorDemo { public static void main(String[] args) { Collection c = new ArrayList(); c.add("one"); c.add("#"); c.add("two"); System.out.println(c); /* * 遍历集合 * 1:获取用于遍历当前集合的迭代器 * 2:一次问一个,取一个,删一个 */ Iterator it = c.iterator(); while(it.hasNext()) {//问 String str = (String)it.next();//取 System.out.print(str+" "); if("#".equals(str)) { // c.remove(str); //迭代器要求在遍历的过程中不能通过集合的方法增删元素,否则遍历过程会抛出异常; it.remove();//删,迭代器自带的删处方法,一次删除一个 } } System.out.println(); System.out.println(c); } } 【增强for循环】,也称为新循环,for each package collection; /** * jdk5之后退出了一个特性:增强for循环 * 增强for循环也称为新循环,for each * 作用是遍历数组或遍历集合使用,所以不取代传统for循环工作 * * 新循环并非jvm认可,而是编译认可,使用新循环遍历数组最终会被编译器在编译时改变为传统的for循环遍历; */ //遍历数组 public class NewForDemo { public static void main(String[] args) { String[] array = {"one","two","three","four","five"}; //传统循环遍历 for(int i=0;i<array.length;i++) { String str = array[i]; System.out.print(str+" "); } System.out.println(); //新循环 for(String str : array) { System.out.print(str+" "); } System.out.println(); } } //遍历集合 package collection; import java.util.ArrayList; import java.util.Collection; /** * 新循环遍历集合 */ public class NewForDemo2 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("one"); c.add("#"); c.add("two"); System.out.println(c); for(Object o : c) { String str = (String)o; System.out.println(str); } //新循环遍历集合会被编译器改变为迭代器遍历, //所以在新循环遍历集合的过程中不要对集合元素做增删操作,否则抛异常ConcurrentModifiationException } }
【泛型】
1 package collection; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 6 /** 7 * jak5之后推出了特性:泛型 8 * 泛型也称为参数化类型,允许我们在使用某个类时,传入指定的类型来约束该类中某个属性,方法的参数或返回值的类型 9 * 这样做可以提高代码的灵活性 10 * 泛型最常用的地方就是集合中,用于约束集合中的元素类型 11 *例如:<String>,<Integer>,<Double>,<Boolean> 12 */ 13 public class CollectionDemo6 { 14 public static void main(String[] args) { 15 Collection<String> c = new ArrayList<String>(); 16 /* 17 * 由于add方法参数类型为泛型,这里编译器会检查实际传入的参数是否符合该泛型要求,不符合编译不通过 18 */ 19 c.add("one");//编译器检查实参是否为String类型 20 c.add("two"); 21 c.add("three"); 22 c.add("four"); 23 System.out.println(c); 24 //由于集合指定了泛型,新循环遍历可以直接使用String接收 25 for(String str:c) { 26 System.out.println(str); 27 } 28 29 } 30 }
第十一章 List & Set
* Collection接口下面有两个常用的派生接口“
* java.util.List; 线性表,特点:可重复,有序。即相同元素可以重复放入集合;
* java.util.Set; 元素不可重复;默认无序,但是有有序的实现方法;
【List】
* java.util.List 接口
* List是可重复集合,特点是有序,提供了一组通过下标操作元素的方法
* 通用实现类:
* java.util.ArrayList:数组实现,查询效率好,增删慢
* java.util.LinkedList:链表实现,增删效率好,尤其首尾增删元素效率最高,查询慢;
List<Integer> list = new ArrayList<Integer>();
list.get(int index); 获取指定下标位置的元素;
list.set(int index,E e); 将指定下标位置的元素替换为新元素;
list.add(int index,E e); 将给定元素插入到指定位置;
list.remove(int index); 删除并返回指定位置对应的元素;
list.subList(int fromIndex, int toIndex); 获取集合的子集,包头不包尾;
用subList()获取子集后,对子集的操作就是对原集合对应元素的操作;
list.subList(2,5).clear(); 可以看做是对原集合第三到第五个元素的删除;
【集合转换为数组】:
list.toArray(); jdk5之前集合提供了转数组的无参方法,返回值是Object类型,需强转
list.toArray( new String[list.size()] ); jdk5之后集合提供了转数组的有参方法,参数为需要转换的数组对象,集合按参数数组类型转换为数组
【数组转集合】:
数组的工具类:Arrays提供了一个静态方法asList(),该方法可将一个数组转换为一个List集合
List<String> list = Arrays.asList(arr);
数组转换为集合后,对集合元素的修改就是对原数组对应元素的修改;
并且不支持添加新元素或删除已有元素;
(否则报异常:UnsupportedOperationException)
若希望增删元素,需要重新创建一个集合;
所有集合都提供了一个参数为Collection的构造方法,
作用是在创建当前集合的同时包含给定集合中的所有元素
List<String>list2 = new ArrayList<String>(list);
//创建list2的同时包含list的所有元素
【小案例】
* 将子集每个元素扩大10倍
for(int i = 0; i < subList.size() ; i++ ){ int num = subList.get(i); subList.set(i, num*10); } System.out.println(subList);
【集合排序】
集合工具类:Collections
其提供了很多操作集合的静态方法,其中sort(List list)方法是对List集合进行自然排序(从小到大)
Collections.sort(List list);
用该方法排序自定义类型元素的集合时,要求集合元素必须实现Comparable接口,否则编译不通过;
例如:class Point implements Comparable<Point>{
重写compareTo方法
* 该方法的意义是定义当前对象(this)与参数对象(o)之间的大小关系
* 返回值int,返回值不关注具体取值,只关注取值范围
* 当返回值>0,当前对象大于参数对象this>o
* 当返回值=0; this==o
* 当返回值<0, this<o
}
Collections.sort(List list)方法排序集合存在两点不足:
1:由于依赖集合元素自身的比较规则,所以强制要求集合元素必须实现Comparable接口并重写比较规则,这会导致我们在排序自定义元素时必须做此事;那么我们称该方法对我们的程序有侵入性。(使用某个功能时,其要求我们改的代码越多侵入性越强)
2:java提供了很多类实现了Comparable接口,比如Integer,String等;
但有时候它们提供的比较规则不满足我们对于元素的排序需求,这时该sort方法也无法使用;
Collections提供了另一个重载的sort方法,可以单独指定一个比较器Comparator,这种方式解决了之前sort方法的两个不足,实际开发中推荐使用这种方式。
【例】按字符串的长短排序,制作比较器
Comparator com = new Comparator(){ public int compare(String s1 , String s2){ return s1.length()-s2.length(); } }; Collections.sort( list , com );
【队列】Queue
java.util.Queue;队列
a:队列也可以保存一组元素,但是存取元素必须遵循先进先出原则;
queue.offer("one");//入队操作,等同于add();
queue.poll(); //出队操作,获取队首元素并将之移除
queue.peek(); //引用队首元素,并不移除
【双端队列】
java.util.Deque;双端队列,继承自Queue接口
b:双端队列是两端都做进出队操作的队列,常用实现类LinkedList
deque.offer("one");//入队操作,等同与add()
deque.offerFirst("two");//将two添加到队首
deque.offerLast("three");//将three添加到队尾
deque.poll(); //出队操作,获取队首元素并将之移除
deque.pollFirst(); //获取队首元素并将之移除
deque.pollLast(); //获取队尾元素并将之移除
【栈队列】
stack栈结构,通过双端队列来实现
c:栈也可以保存一组元素,但是存取元素必须遵循先进后出原则;
Deque接口为栈提供了相应的方法:push,pop
stack.push("one");//将one放入栈口;
stack.pop(); //获取栈口元素并将之移除
java实际开发中经常使用栈实现“后退”这样的功能;