第一部分 Collections
一.概述
集合框架的工具类,里面的方法都是静态的。
二.常用方法:
1.排序:
void sort(List<T> list);//根据元素的自然顺序 对指定列表按升序进行排序。
void sort(List<T> list, Comparator<? super T> c);//根据指定比较器产生的顺序对指定列表进行排序。
自定义实现排序的函数方式一:
public <T extends Comparable<? super T>> void mySort(List<T> list){
for(int i=0;i<list.size();i++){
for(int j=i-1;j<list.size();j++){
if(list.get(i).compareTo(list.get(j))>0){
Collections.swap(list, i, j);
}
}
}
}
自定义实现排序的函数方式二:
public <T> void mySort(List<T> list,Comparator<T> comp){
for(int i=0;i<list.size();i++){
for(int j=i-1;j<list.size();j++){
if(comp.compare(list.get(i), list.get(j))>0){
Collections.swap(list, i, j);
}
}
}
}
2.交换位置:
void swap(List<?> list, int i, int j);//在指定列表的指定位置处交换元素
3. 查找:
<T> int binarySearch(List<? extends Comparable<? super T>> list, T key);//使用二分查找法搜索指定列表,以获得指定对象。使用自然顺序。
<T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c);//使用二分查找法搜索指定列表,以获得指定对象。使用比较器顺序。
4.最值:
T max(Collection<? extends T> coll);//根据元素的自然顺序,返回给定 collection 的最大元素。
T max(Collection<? extends T> coll, Comparator<? super T> comp);//根据指定比较器产生的顺序,返回给定 collection 的最大元素。
T min(Collection<? extends T> coll);//根据元素的自然顺序 返回给定 collection 的最小元素。
T min(Collection<? extends T> coll, Comparator<? super T> comp);//根据指定比较器产生的顺序,返回给定 collection 的最小元素。
5.逆序:
void reverse(List<?> list);//反转指定列表中元素的顺序。
Comparator<T> reverseOrder();//返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
Comparator<T> reverseOrder(Comparator<T> cmp);//返回一个比较器,它强行逆转指定比较器的顺序。
6.替换:
boolean replaceAll(List<T> list, T oldVal, T newVal);//使用另一个值替换列表中出现的所有某一指定值。
void fill(List<? super T> list, T obj);//使用指定元素替换指定列表中的所有元素。
7.乱序:
void shuffle(List<?> list);//使用默认随机源对指定列表进行置换。
void shuffle(List<?> list, Random rnd);//使用指定的随机源对指定列表进行置换。
8.枚举:
Enumeration<T> enumeration(Collection<T> c);//collection转枚举。
ArrayList<T> list(Enumeration<T> e);//枚举转ArrayList。
9.集合同步转换:
Collection<T> synchronizedCollection(Collection<T> c);//返回指定 collection 支持的同步collection。
List<T> synchronizedList(List<T> list);//返回指定列表支持的同步列表。
Map<K,V> synchronizedMap(Map<K,V> m);//返回由指定映射支持的同步映射。
Set<T> synchronizedSet(Set<T> s);//返回指定 set 支持的同步set。
SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m);//返回指定有序映射支持的同步有序映射。
<T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s);//返回指定有序 set 支持的同步有序set。
第二部分 Arrays
一.概述
集合框架的工具类,里面的方法都是静态的。
二.操作方法:
1.二分查找
int binarySearch( );//使用二分查找法,返回数组的索引。有大量的重载
2.复制
copyOf();//从索引0开始从指定数组中复制指定的长度,小于原长就截取,大于原长就填充false、0或者null,返回复制的结果。
copyOfRange();//将指定数组的指定范围复制到一个新数组。返回复制的结果。
3.比较
equals();//如果两个数组长度相同,并且对应元素对都是相等的,则这两个数组相等,放回true;否则返回false。
boolean deepEquals(Object[] a1, Object[] a2);//深度比较,即如果两个数组引用均为 null,或者它们引用了包含相同元素数量的数组,并且两个数组中的所有相应元素对都是深层相等的,则认为这两个数组引用是深层相等的。
4.填充
fill();//将指定数组的指定范围填充为某个元素值。
5.排序
sort();//根据元素的值、自然顺序或者根据传入的比较器,对数组进行排序。
6.字符串转换
String toString();//将数组中的元素转换为字符串的形式,作为结果返回。
7.哈希码计算
int hashCode();//基于指定数组的内容返回哈希码。
int deepHashCode(Object[] a);//基于深层内容的哈希码计算。
8.列表转换
List<T> asList(T... a);//将可变参数或数组转换为固定大小的列表。
好处:这样就可以使用集合的方法操作数组中的元素了。
注意:1>数组的长度是固定的,所以对于集合的增删方法是不可以使用的。
2>如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。如果数组中的元素是基本类型值,那么会将该数组作为集合的元素进行存储。
三.集合转数组
与Arrays的asList方法的数组专辑和对应,Collection中也有toArray方法将集合转为数组。
这样可以对集合中的元素操作的方法进行限定。并且不允许对转换后的数组进行增删。
对于 <T> T[] toArray(T[] a);这个方法,的使用toArray(new String[1]);
传入一个指定类型的数组,如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组;如果长度大于集合的size,那么该方法就会使用指定的数组存储集合中的元素,其他位置默认为null。所以建议,长度就指定为集合的size。
四.使用案例
判断数组中是否包含摸个元素:
String[] strs={"aaa","bb","ccc"};
List list=Arrays.asList(strs);
boolean flag=list.contains("ccc");
第三部分 泛型
一.概述
1.JDK1.5出现的安全机制。
2.好处:1>将运行期间的问题ClassCastException转到编译时期。
2>避免强制转换的麻烦。
3.<>什么时候使用?
当操作的引用数据类型不确定的时候,就使用<>将要操作的引用数据类型传入即可。
其实<>就是一个用于接收具体引用数据类型的参数范围。
在程序中只要用到了带有<>的类或接口,就要明确传入的具体引用数据类型。
4.泛型技术是给编译器使用的技术,用于编译时期确保类型的安全性。
5.运行时会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。为什么擦除呢?因为为了兼容运行的类加载器。
6.泛型补偿机制:在运行时通过获取元素的类型进行转换动作。不用使用者再强制转换了。
二.泛型基本使用举例
1.
ArrayList<String> al=new ArrayList<String>();
al.add("abc");
al.add("def");
al.add("ghi");
Iterator<String> it=al.iterator();
while(it.hasNext()){
String str=it.next();
System.out.println(str);
}
2.在自然排序比较器中使用泛型
自然排序比较器中compare方法内部就不需要再进行类型判断和类型强制转换。
public class Person implements Comparable<Person>{
private String name;
private int age;
@Override
public int compareTo(Person o) {
int temp=this.age-o.age;
return temp==0?this.name.compareTo(o.name):temp;
}
}
3.Compartor比较器使用泛型
public class MyComparator implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
int temp=o1.getName().compareTo(o2.getName());
return temp==0?o1.getAge()-o2.getAge():temp;
}
}
三.泛型定义--泛型类
在JDK1.5后,使用泛型来接收类中要操作的引用数据类型。这就是泛型类。
当类中操作的数据类型不确定的时候,就是用泛型表示。
public class Tool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
四.泛型定义--泛型方法
1.在方法的返回值之前用<>定义泛型,那么在方法的参数和方法体中就可以使用这个泛型了。
public static <W> void show(W obj){
System.out.println(obj.toString());
}
2.当类中的方法是静态方法时,不能访问类上定义的泛型,只能将泛型定义在方法上。
public <Y> void Method(Y obj){
System.out.println(obj.toString());
}
3.在使用泛型方法时不需要像泛型类一样先显式的在类定义时就确定类型。只需像使用普通方法一样即可。
Person p=new Person();
p.show("sbc");
Person.Method(45);
4.当使用泛型方法时,泛型所对应的对象只能使用Object类的方法。
五.泛型定义--泛型接口
1.定义一个泛型接口
interface Inter<T>{
void show(T t);
}
2.实现接口时明确类型
class InterImpl implements Inter<String>{
@Override
public void show(String str) {
System.out.println("show :"+str);
}
}
3.实现接口时不明确类型,继续用泛型
class InterImpl2<Q> implements Inter<Q>{
@Override
public void show(Q q) {
System.out.println("show :"+q);
}
}
4.使用上面用泛型接口定义的泛型类
InterImpl in=new InterImpl();
in.show("aaaaa");
InterImpl2<Integer> in2=new InterImpl2<Integer>();
in2.show(34);
六.泛型的通配符:<?>
通配符使用举例:
public void printCollection(Collection<?> coll){
Iterator<?> it = coll.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
其作用完全可被泛型方法所替代。
当方法中不使用泛型的类型操作时,为简单起见可以用通配符<?>
使用泛型方法替代上面的代码:
public static <T> void printCollection(Collection<T> coll){
Iterator<T> it = coll.iterator();
while(it.hasNext()){
T t=it.next();
System.out.println(t);
}
}
七.泛型限定--上限:<? extends E>
<? extends E>用来接收E类型或E的子类型,上限!
其实,<?>即为<? <? extends Object>
泛型上限使用举例:
//Person是由name和age属性的JavaBean
//Student和Worker继承了Person类
//泛型的上限,能接受Person的子类即Student和Worker
定义代码:
public void printCollection(Collection<? extends Person> coll){
Iterator<? extends Person> it = coll.iterator();
while(it.hasNext()){
Person p=it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
使用代码:
TreeSet<Person> coll1=new TreeSet<Person>();
TreeSet<Student> coll2=new TreeSet<Student>();
TreeSet<Worker> coll3=new TreeSet<Worker>();
printCollection(coll1);
printCollection(coll2);
printCollection(coll3);
八.泛型的限定--下限:<? super E>
<? super E>用来接收E类型或E的父类型,下限!
泛型下限使用举例:
定义代码:
<span style="white-space:pre"> </span>//泛型的下限,只能接受Student和Student的父类Person
public static void printCollection(Collection<? super Student> coll){
Iterator<? super Student> it = coll.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
使用代码:
TreeSet<Person> coll1=new TreeSet<Person>();
TreeSet<Student> coll2=new TreeSet<Student>();
printCollection(coll1);
printCollection(coll2);
九.泛型限定在集合中的体现
1.上限的体现
一般向集合中存储元素时使用上限。
Collection的方法:
boolean addAll(Collection<? extends E> c)
定义一个集合其中的元素类型为E,可用addAll方法将另一个集合中的元素添加到本集合中。另一个集合中的元素类型可以是E或E的子类型,这样能增强扩展性。
2.下限的体现
通常对集合中的元素进行去除操作时,可以使用下限。
TreeSet的构造方法:
TreeSet(Comparator<? super E> comparator)
当比较器进行比较时,会从集合中取出元素。若集合中的元素是Student类型,取出后可把它提升为Person类型进行比较;若集合中的元素是Worker类型,则依然可以使用此比较器把Worker的元素转为Person进行比较。
这样可提高比较器的适用范围,即这个比较器可用于比较以Person类的子类为元素的所有集合。
3.通配符的体现
ArrayList的方法:
boolean removeAll(Collection<?> c)
当只使用集合元素从Object继承来的方法时,可用<?>。
还有当返回一个集合时不需要进行详细的类型区分,可使用<?>。