------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1、泛型
1.概述
泛型是JDK1.5之后出现的新特性。用于解决安全问题,是一个安全机制。明确表明你要向集合中装入那种类型的数据,无法加入指定类型以外的数据。通过<>来定义要操作的引用数据类型。
好处
1. 将运行时出现的ClassCastException,转移到了编译时期,方便了程序员解决问题,让运行时期减少,安全。
2.避免了强制转换的麻烦。
2.类型
1.定义在类上
如果类型确定后,所操作的方法都是属于此类型,则定义泛型类。
class Util<QQ >
{
private QQ a;
public void setObject(QQ a)
{
this.q=q;
}
public QQ getObject()
{
return a;
}
}
2.定义在方法上
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象要明确操作的具体类型后,所有要操作的类型已经确定了。
为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。
package com.blog.part4.集合;
class Demo
{
public <T> void show(T t)
{
System.out.println("show:"+t);
}
public<Q>void print(Q q)
{
System.out.println("print:"+q);
}
}
public class Test1
{
public static void main(String[] args)
{
Demo d=new Demo();
int [] arr={1,2,3};
//可以看到show能接收任何类型
d.show("haha");
d.show(arr);
d.print(new Integer (4));
}
}
注意:
当同时在类和类中的方法上都定义了泛型时,按照具体方法上的泛型走。
特殊之处:静态方法不可以访问类上定义的泛型,如果操作的数据类型不确定,可以在方法上定义泛型。泛型放在方法上
返回值类型的后边。
3.泛型限定
1. <?>通配符(占位符)泛型,代表所有类型。
2.如果只想打印一个范围。<? extends E >这里E可以接收E类型,或者E的子类。上限。
super E:可以接受E类型或者E的父类型,下限。
2、集合框架工具类
1.Collections
Collections是对集合框架的一个工具类。它里边的方法都是静态的,不需要创建对象。并未封装特有数据。
在Collections工具类中大部分方法是用于对List集合进行操作的,如比较,二分查找,随机排序等。
2.常见操作
1、查找
T max(Collection<? extends T> coll);//根据集合的自然顺序,获取coll集合中的最大元素
T max(Collection<? extends T> coll,Comparator<? super T> comp);//根据指定比较器comp的顺序,获取coll集合中的最大元素
int binarySearch(Lsit<? extends Comparable<? super T>> list,Tkey);//二分法搜索list集合中的指定对象
package com.blog.part4.集合;
import java.util.*;
public class Test2
{
public static void main(String[] args)
{
//定义一个LinkedList集合
LinkedList arr=new LinkedList();
arr.add("d");
arr.add("c");
arr.add("a");
arr.add("e");
//使用max方法
String st=Collections.max(arr);
System.out.println(st);
//使用二分查找
int index=Collections.binarySearch(arr, "c");
System.out.println(index);
}
}
2、替换
void fill(List<? super T> list, T obj);//将list集合中的全部元素替换成指定对象obj
boolean replaceAll(List<T> lsit,T oldVal,T newVal);//用newVal替换集合中的oldVal值
void swap(List list,int i,int j);/在指定列表的指定位置处交换元素
package com.blog.part4.集合;
import java.util.*;
public class Test3
{
public static void main(String [] args)
{
//定义两个集合at和at1分别赋值
ArrayList at =new ArrayList();
ArrayList at1=new ArrayList();
at.add("ab");
at.add("abc");
at.add("abc");
at.add("bc");
at1.add("x");
at1.add("y");
at1.add("z");
sop(at);
sop(at1);
sop("-----------------------------------");
//替换
String t="haha";
Collections.fill(at, t);
sop(at);
//替换元素
Collections.replaceAll(at1, "y", "w");
sop(at1);
//交换元素
Collections.swap(at1,0,1);
sop(at1);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
3、排序:
void shuffle(List<?> list);//使用默认随机源对list集合中的元素进行随机排序
void sort(Lsit<T> list);//根据自然顺序对list集合中的元素进行排序
void sort(List<T> lsit,Comparator<? super T> c);//根据指定比较器c的排序方式对list集合进行排序
4、反转
reverse(List<?> list);//反转list集合中元素的顺序
Comparator reverseOrder();//返回一个比较器,强行逆转了实现Comparable接口的对象的自然顺序
Comparator reverseOrder(Comparator<T> cmp);//返回一个比较器,强行逆转了指定比较器的顺序
5、同步的集合
List<T>synchronizedList(List<T> list);//返回支持的同步(线程安全的)List集合
Map<K,V>synchronizedList(Map<K,V> m
代码示例:
/**
* 需求:练习Collections的常用方法
* @author jinlong
* */
package com.blog.part4.集合;
import java.util.*;
//定义一个Person类
class Person
{
//私有属性
private String name;
private int age;
Person(String name ,int age)
{
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;
}
//equals重写
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) 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;
}
}
//自定义一个比较器
class MyCmp implements Comparator<Person>
{
public int compare(Person p1,Person p2)
{
//姓名是主要排序条件
int num=p1.getName().compareTo(p2.getName());
if(num==0)
return p1.getAge()-p2.getAge();
return num;
}
}
public class CollectionsDemo
{
public static void main(String[] args)
{
//定义集合并且赋值
ArrayList<Person> at=new ArrayList<Person>();
at.add(new Person("lilei",19));
at.add(new Person("lilin",20));
at.add(new Person("wanger",21));
at.add(new Person("ayun",22));
//打印自然排序
sop("-------------自然排序----------------");
forPrint(at);
sop("-------------逆反自然排序----------------");
Collections.reverse(at);
forPrint(at);
sop("-------------自定义比较器排序后----------------");
//实例化一个比较器,
MyCmp mp=new MyCmp();
//使用比较器排序
Collections.sort(at, mp);
forPrint(at);
sop("-------------逆转自定义比较器----------------");
//获取自定义比较器的逆转效果
Comparator ro=Collections.reverseOrder(mp);
Collections.sort(at, ro);
forPrint(at);
sop("-------------reverse后----------------");
Collections.reverse(at);
forPrint(at);
sop("-------------shuffle排序后----------------");
Collections.shuffle(at);
forPrint(at);
}
//打印方法
public static void sop(Object obj)
{
System.out.println(obj);
}
//增强for打印
public static void forPrint(ArrayList<Person> at)
{
for(Person p:at)
{
sop(p.getName()+"::"+p.getAge());
}
}
}
运行结果:
3.Collection和Collections的区别
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。
它有两个常用的子接口:
List:对元素都有定义索引。有序的。可以重复元素。
Set:不可以重复元素。无序
Collections是集合框架中的一个工具类。该类中的方法都是静态的。提供的方法中有可以对list集合进行排序,二分查找等方法
2.Arrays
1.概念
Arrays是用于操作数组的工具类。里边的方法也全是静态的。不需要创建对象。
把数组变成List集合的好处:可以使用集合的思想和方法来操作数组中的元素。
2.常用方法
1.将数组转换为集合:Lsit<T> asList(T... a);
a、将数组转换成集合,不可使用集合的增删方法,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException 的编译异常。
b、如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。
c、如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。
2. binarySearch():二分查找方法,fill():替换方法,sort():排序方法等
特点:可对数组元素进行相应操作,可以接受除boolean之外的其他各种基本数据类型及有序的引用类型数组的参数,且还可以对指定元素的范 围,并可根据指定比较器进行相应的操作。
如:sort(T[]a,Comparator<? super T> c)
fill(int[]a,int from,int to)等
3.toString();/
可以接收各种数组类型参数,并返回指定数组内容的字符串表现形式。
示例:
class ArraysDemo
{
public static void main(String[] args)
{
int[] arr = {2,4,5};
System.out.println(Arrays.toString(arr));//转换为字符串形式
String[] arr = {"abc","cc","kkkk"};//字符串数组
List<String> list = Arrays.asList(arr);
sop("contains:"+list.contains("cc"));//判断是否存在"cc"这个元素
Integer[] nums = {2,4,5};
List<Integer> li = Arrays.asList(nums);
sop("asList--Integer[]转集合:" + li);
}
//打印方法
public static void sop(Object obj)
{
System.out.println(obj);
}
}
4.集合变数组
Collections接口中的toArray方法。
<T> T[]toArray(T[] a);将集合变为指定类型的数组。
1、指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。
当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。
所以创建一个刚刚好的数组最优。
String[ ] arr=al.toArray(new String[ al.size()])
2、为什么要将集合变数组?
为了限定对元素的操作。不需要进行增删了。
class CollectionToArray
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
//将集合变为String数组
String[] arr = al.toArray(new String[al.size()]);
//利用Arrays操作数组的方法
System.out.println(Arrays.toString(arr));
}
}
3、JDK1.5新特性
1.增强for循环
for(数据类型 变量名:被遍历的集合)
只能获取元素,但是不能对集合进行操作。
迭代器除了遍历,还能进行remove的动作,如果使用ListIterator,还可以在遍历中进行增删改查的操作。
2.方法的可变参数
如果一个方法在参数列表中传入多个参数,个数不确定,那么每次都要复写该方法。这时可以用数组作为形式参数。但是在传入时,每次都需要定义一个数组对象,作为实际参数。在JDK1.5版本后,就提供了一个新特性:可变参数。
可变参数其实就是数组参数的简写形式。不用每一次都手动的建立数组对象。只要将要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。
在使用时注意:可变参数一定要定义在参数列表的最后面。
{
public static void main(String[] args)
{
show("haha",2,3,4,5,6);
}
public static void show(String str,int... arr)//...就表示可变参数
{
System.out.println(arr.length);
}
}
3.静态导入
1、写法:
import staticjava.util.Arrays.*;//导入的是Arrays这个类中的所以静态成员。
import staticjava.lang.System.*//导入了Ssytem类中所以静态成员。
没加static导入的是类,加上static导入的全是某一个类中所以的静态成员。这样写在调用该类的静态方法时可以不用再写类名。 如:Arrays.sort(数组);就可以直接写sort(数组);
2、注意:
当导入的两个类中有同名成员时,需要在成员前加上相应的类名。
当类名重名时,需要指定具体的包名。当方法重名时,指定具体所属的对象或者类。
import static java.util.Arrays.*;
import static java.lang.System.*;
class StaticImport //extends Object
{
public static void main(String[] args)
{
out.println("haha");//打印输出时就可以直接省略书写System.
int[] arr = {3,1,5};
sort(arr);//使用Arrays工具类的方法sort时就可以省略书写Array.
int index = binarySearch(arr,1);//半分查找也是一样可以省略
out.println("Index="+index);
//当没有指定继承时,所以类默认继承了Object,
//因为toString方法都具备,所以为了区分,必须写上具体调用者
out.println(Arrays.toString(arr));
}
}