泛型
在某些情况下,在定义类型的时候不方便限定类型中需要使用的数据(对象)的类型。
泛型类:在类名后面添加了类型参数声明部分。泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。
//filename:Genericity01.java
//@author Gonson
public class Genericity01 {
public static void main(String[] args) {
//对Human类进行实例化时,要将泛型具体到某一个类型(从广泛 到 具体 )
//所以当不方便限定类型中需要使用的数据(对象)的类型时,通过泛型可以接收不同类型的参数
Human<Man> humanM = new Human<>();
humanM.whatSex(new Man());
//当实例化带有泛型的类时,如果没有声明 泛型标志 对应的类型,那么默认会声明是Object类。
//虽然在eclipse中会提示告警“泛型类型的引用应参数化”,但以下声明是可以编译和执行的
Human humanW = new Human();
humanW.whatSex(new Woman());
//所以在一些情况下,泛型的功能与 Object 类的功能类似。
HumanObject humanO = new HumanObject();
humanO.whatSex(new Man());
//泛型可以生产变量,可以做方法的返回值。
//<T> T不能创建对象,因为不知道T的构造方法怎么样的。
HumanB<Man, Woman> humanMW = new HumanB<>();
humanMW.whatSexM(new Man());
humanMW.whatSexW(new Woman());
}
}
//定义一个带有泛型的 人 类
class Human<T>{
public void whatSex(T t){
System.out.println(t);
}
}
class HumanObject{
public void whatSex(Object o){
System.out.println(o);
}
}
//泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开
class HumanB<M, W>{
public void whatSexM(M t){
System.out.println(t);
}
public void whatSexW(W t){
System.out.println(t);
}
}
//男人
class Man{
@Override
public String toString() {
return "male";
}
}
//女人
class Woman{
@Override
public String toString() {
return "female";
}
}
/*执行结果
male
female
male
male
female*/
泛型方法:该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。
public class Genericity02 {
public static void main(String[] args) {
Integer[] a = {23,54,54,12,32,59};
System.out.println(genTest(a));
}
//声明一个带泛型的方法,返回类型也可以根据泛型而定。
public static <E> E genTest(E[] ele){
for (E e : ele) {
System.out.print(e + " ");
}
System.out.println("\n****");
return ele[0];
}
}
泛型统配符:?
public class Genericity03 {
public static void main(String[] args) {
callDog(new Dog<String>());
}
//当通过带泛型的类来实例化一个对象时,而类又不确定 可以用通配符来代替
public static void callDog(Dog<?> d){
System.out.println("test");
}
}
class Dog<T> {
//一个带泛型的类
}
泛型的上限:要求是某个类的或其子类,不能是其父类。
//通配符? 的上限是B, 只能代表B类或 B的子类
public static void callDog(A<? extends B> c){
System.out.println("test");
}
泛型的下限:要求是某个类的或其父类,不能是其子类。
//通配符? 的上限是B, 只能代表B类或 B的父类
public static void callDog(A<? super B> c){
System.out.println("test");
}
高级API之克隆(Cloneable)
每个类都继承了Object 的clone 方法,但是Object.clone这个公共方法是受保护的,如果没有实现Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常。 当实现了Cloneable 接口,便可以 Object.clone() 方法可以合法地对该类实例进行按字段复制。
public class TheMain {
public static void main(String[] args) throws CloneNotSupportedException {
Dog d1 = new Dog("DaBan", 4);
//把d1 赋值给 d2 其实就是d1,d2指向了同一个对象
Dog d2 = d1;
//clone 就是把原来的 对象完整的克隆一份,是一个新的对象
Dog d3 = (Dog) d1.clone();
//d2 setName 对象的改变也影响到了d1
d2.setName("XiaoBan");
//d3 setName 只是改变自己
d3.setName("WangCai");
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
}
}
class Dog implements Cloneable{
private String name;
private int age;
public Dog(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Name=" + name + ", Age=" + age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
上面的例子是浅克隆,如果类属性用有 引用类型对象 的时候,clone 只能clone引用的对象的指针(引用),不能克隆引用的对象。这是时候就要进行深克隆(多层克隆)。
class Person implements Cloneable{
private String name;
private Dog dd;
public Person(String name, Dog dd) {
super();
this.name = name;
this.dd = dd;
}
public void setName(String name) {
this.name = name;
}
public void setDd(Dog dd) {
this.dd = dd;
}
@Override
public String toString() {
return "PersonName:" + name + "\t\t DogInfo: " + dd.toString();
}
@Override
protected Object clone() throws CloneNotSupportedException {
//先把自己克隆给temp
Person temp = (Person) super.clone();
//把person的Dog 克隆。
//如果没有这操作,只是浅克隆,原来person的dog 和克隆的dog 是两个引用同一个对象,
temp.dd = (Dog) this.dd.clone();
return temp;
}
}
高级API之比较(Comparable)
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
//这个Student类实现了Comparable 接口
class Student implements Comparable<Student>{
int Score; //有一个Score 属性
//覆写 compareTo比较器
@Override
public int compareTo(Student o) {
//根据情况返回 1 / -1 / 0
if (this.Score > o.getScore()) return 1;
else if (this.Score < o.getScore()) return -1;
else return 0;
}
public int getScore() {
return Score;
}
}
Comparable 接口应用在 对象数组的比较,可以实现排序。
在Arrays类有sort方法,就是根据比较器来实现的。Array.sort()根据指定比较器产生的顺序对指定对象数组进行排序。数组中的所有元素都必须是通过指定比较器可相互比较的(也就是说,对于数组中的任何 e1 和 e2 元素而言,c.compare(e1, e2) 不得抛出 ClassCastException)。
StringBuffer
Stringbuffer, StringBuilder
Java 中string 对象是只读的,某些情况在处理多个的string对象导致内存浪费、
因而引入Stringbuffer, StringBuilder来动态处理字符串,除了类的名字不一样其他都一样
stringBuffer 是异步的,速度底线程安全,
stringBuilder 是同步的,速度快,线程不安全。
StringBuffer 和 StringBuilder 的方法大致相同,在处理字符串上功能比String优,具体通过JavaAPI熟悉使用。
Collection
(集合:集合是类型的对象的一种引用存储形式)
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现。此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。
Collection接口常用的实现类有: , HashSet, TreeSet, ArrayList, LinkedList, Vector,Arrays, AbstractCollection,HashMap,TreeMap 等等
Arrays:此类包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂。
ArrayList: List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。
HashSet:此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
TreeSet:基于 TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
TreeMap:基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
HashMap:基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。