Java基础知识思维导图
什么是集合?
- 概念:对象的容器,存储对象的对象,可代替数组。
- 特点:容器的工具类(带有工具的容器),定义了对多个对象进行操作和常用方法。
- 位置:java.util.*;
Collection体系集合
- Interface Collection 该体系结构的根接口,代表一组对象,称为“集合”,每个对象都是该集合的“元素”。一些集合允许重复元素,有一些有序有一些无序。JDK不提供此接口的任何直接实现:它提供了更具体的子接口的实现,如Set和List。
- List接口:有序、有下标、元素可重复
- Set接口:无序、无下标、元素不能重复
Collection父接口
- 特点:代表一组任意类型的对象,无序无下标。
- 方法:
boolean add(Object obj)//添加一个对象。
boolean addAll(Collection c)//将一个集合中的所有对象添加到此集合中。
void clear()//清空此集合中的所有对象。
boolean contain(Object o)//检查此集合中是否包含o对象
boolean equals(Object o)//比较此集合是否与指定对象相等。
boolean isEmpty()//判断此集合是否为空
boolean remove(Object o)//在此集合中移除o对象
int size()//返回此集合中的元素个数。
Object[] toArray() //将此集合转换成数组。
List集合
- 特点:有序、有下标、元素可以重复。可继承父接口提供的共性方法。同时定义了一些独有的与下标相关的操作方法。
- 方法:
void add(int index,Object o)//在index位置插入对象o。
boolean addAll(int index,Collection c)//将一个集合中的元素添加到此集合中的index位置。
Object get(int index)//返回集合中指定位置的元素。
List subList(int formIndex,int toIndex)//返回fromIndex和toIndex之间的集合元素。
Iterator迭代器
专注于迭代Collection体系集合的
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class TestIterator {
public static void main(String[] args) {
//对于Collection体系集合进行遍历
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
//1.获得一个迭代器
//hasNext();是否有下一个元素进行遍历,有就返回true,没有false
//next(); 返回下一个元素
Iterator<String> iter = list.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
Set<String> sets = new HashSet<String>();
sets.add("E");
sets.add("F");
sets.add("G");
sets.add("H");
Iterator<String> si = sets.iterator();
while(si.hasNext()) {
System.out.println(si.next());
}
}
}
List实现类
- ArrayList【重点】:
数组结构实现,查询快、增删慢;
JDK1.2版本,运行效率快、线程不安全。 - Vector:
数组结构实现,查询快、增删慢;
JDK1.0版本,运行效率慢、线程安全。 - LinkedList:
链表结构实现,增删快,查询慢。
import java.util.ArrayList;
public class TestArrayList {
public static void main(String[] args) {
ArrayList al = new ArrayList();//对象的容器,存储对象的对象
boolean result = al.add("HelloWorld");//存储到了Object[]中的下标0的元素下
System.out.println(result);
Object obj =al.get(0);//将底层Object[]中下标0的元素返回
System.out.println(obj);
Object[] objs = new Object[10];//原本对象数组,加入方法逻辑和限制则有了ArrayList
objs[0]="HelloWorld";
System.out.println(objs[0]);
}
}
List实现类:
- JDK8的ArrayList,实际初始长度是0
- 首次添加元素时,需要实际分配数组空间,执行数组扩容操作
- 真正向数组中插入数据,用的时候再创建,或再加载,有效的减低无用内存的空间。
import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
public class TestArrayListMethods {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList();//初始容量为10 长度10
//实际的创建后的数组长度为0,JDK7以及之前,无参构造方法直接创建长度为10的Object数组,占内存
//JDK8之后,无参构造方法直接创建长度为0的数组,如果不用,不占空间,只有当真正插入元素时,再分配数组空间
al.add("A");
al.add("B");
al.add("C");//顺序插入
al.add(1,"E");//按位置插入
for(int i = 0 ; i <al.size();i++) {//访问size()有效元素个数
System.out.println(al.get(i));//get方法基于下标获取元素
}
System.out.println(al.toString());
boolean removeResult = al.remove("E");//按照对象移除
Object removeObj = al.remove(1);//按照下标移除
System.out.println("被移除的对象:"+removeObj);
al.set(0, "F");//根据下表替换新元素
System.out.println(al.toString());
Object[] objs = al.toArray();
for(int i = 0; i <objs.length;i++) {
System.out.println(objs[i]+"\t");
}
al.clear();//清空
System.out.println(al.toString());
//工具方法中(服务集合的工具、服务数组的工作Arrays)
java.util.List<String> list =Arrays.asList("A","B","C","D","E");
System.out.println(list.toString());
}
}
public class TestVector {
public static void main(String[] args) {
//JDK提供了集合的使用方式
//程序员1996年使用了Vector创建对象,调用方法,完成自己的业务功能
//直至JDK1.2发布的版本中,提供更情况的Vector同类型工具——ArrayList
//Vector vector = new Vector();
//List vector = new Vector();
List vector = new ArrayList();//更容易更换具体实现 接口
vector.add(111);//Vector.add(Object o)
vector.add(222);
vector.add(333);
for(int i = 0 ; i<vector.size();i++) {
System.out.println(vector.get(i));
}
System.out.println(vector);
}
}
LinkedList:
- 链表结构存储
- Queue接口:队列、双端队列
- 栈结构后进先出,队列结构先进先出
Collections工具类
- 概念:集合工具类,定义了除了存取以外的集合常用方法
- 方法:
public static void reverse(List<?> list)//反转集合中元素的顺序
public static void shuffle(List<?> list)//随机重置集合元素的顺序
public static void sort(List list)//升序排序(元素类型必须实现Comparable接口)
import java.util.Arrays;
import java.util.List;
public class TestCollectionTool {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1,2,5,6,4,3,7,8,9);
java.util.Collections.sort(numbers);//升序
java.util.Collections.reverse(numbers);//倒置
java.util.Collections.shuffle(numbers);//随机重置
for(int i = 0 ; i<numbers.size();i++) {
System.out.print(numbers.get(i).toString()+"\t");
}
}
}
Set集合
Set子接口
- 特点:无序、无下标、元素不可重复。当插入新元素时,如果新元素与已有元素进行equals比较,结果为true时,则拒绝新元素的插入。
- 方法:全部继承自Collection中的方法。
foreach循环
for(数据类型 变量名:容器名称){
//可遍历集合或数组(常用在无序集合上)
}
import java.util.HashSet;
public class TestHashSet {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.add("A");
set.add("B");
set.add("C");
set.add("D");
System.out.println(set.size());
set.remove("C");
System.out.println(set.size());
System.out.println(set);//展现的是基本类型所以获得的是其地址也是值,若为引用类型则为地址值
//如何获取Set中的元素?
//遍历方式:foreach循环
for(String str:set) {
System.out.print(str+"\t");
}
System.out.println();
}
}
Set实现类
- HashSet[重点]
HashSet的底层使用的HashMap类,即是将所有需要存入HashSet的值,直接存入HashMap中。
HashSet如何去掉重复?
基于HashCode实现元素不重复
当存入元素的哈希码相同时,会调用equals进行确认
import java.util.Set;
public class TestHashSet2 {
public static void main(String[] args) {
Set<Integer> numbers = new HashSet<Integer>();
System.out.println(numbers.add(11));
numbers.add(22);
numbers.add(33);
numbers.add(44);
numbers.add(55);
System.out.println(numbers.add(11));//
for(Integer i:numbers) {
System.out.print(i+"\t");
}
System.out.println();
}
}
HashSet如何去掉重复?
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class TestHashSet3 {
public static void main(String[] args) {//目标:为了了解hashSet数据可以保证唯一的原理是什么?每次调用hhashCode比较是否为同一对象,如果相同则可能是重复对象,或者巧合,所以需要equals
Student s1 = new Student("Tom",20,"male",99.0);//ctrl+1 //导包 //ctrl+shift+o;导入所需全部包
Student s2 = new Student("jack",23,"male",88.0);
Student s3 = new Student("michael",22,"male",95.0);
Student s4 = new Student("annie",21,"female",93.0);
Student s5 = new Student("Tom",20,"male",99.0);//但hashSet会排除这种,因为在hashCode处就有可能被排除了,想让它可以则需要修改
Set<Student> students = new HashSet<Student>();
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
students.add(s1);//插入失败,去掉重复——Object提供的equals方法,内部使用this==obj进行判断
students.add(s5);//地址不同,内容相同(去掉“”重复)
for(Student stu:students) {
System.out.println(stu.toString());
}
//System.out.println(s1.equals(s5));true 证明此时的equals方法可以选出==地址不同但内容相同的类型。
//若直接调用equals方法进行内容比较,此时插入一个元素则需要跟前面的元素进行比较,插6个元素需要比较15次
/*HashSet没有必要在每次插入一个新值时,都去与已有的进行比较。
* HashSet调用equals方法进行比较是具有前提的,两个对象的哈希码都相同
* */
System.out.println(s1.hashCode());//保证同一个对象hashCode相同,但无法保证不同对象hashCode不同//用来排除同一对象
//哈希码不唯一,两个不同对象,巧合般的哈希码相同,hashCode怀疑这两个对象是不是相同对象,此时才会对equals进行二次确认
}
}
class Student{
String name;
Integer age;
String sex;
Double score;
public Student(String name, Integer age, String sex, Double score) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.score = score;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex + ", score=" + score + "]";
}
/*
* hashCode踩死调用equals方法的前提
* 只有当两个对象的hash都相同时,才有必要调用equals方法
*
* */
@Override
public int hashCode() {//equals,其中有s1==s2 || s1.equals(s2)
//return 123;可以去掉重复的目的,但是效率低,还需优化
//return this.age;将年龄作为去比较内容的条件 效率依然低,还需优化
return this.name.hashCode()+this.age.hashCode()+this.sex.hashCode()+this.score.hashCode();
//return super.hashCode();
}
@Override
public boolean equals(Object obj) {
System.out.println("Student's equals Method Executed--");
if(this == obj) {
return true;
}
if(obj == null) {
return false;
}
if(this.getClass() != obj.getClass()) {
return false;
}
Student s = (Student)obj;
if(this.name.equals(name)&&this.age.equals(s.age)&&this.sex.equals(s.sex)&&this.score.equals(s.score)){
return true;
}
return false;
}
}
- LinkedHashSet:
链表实现的HashSet,按照链表进行存储,即可保留元素插入的顺序。
底层使用LinkedHashMap(链表结构)存储,节点形式完成单独数据的保存,并可以指向下一个节点,通过顺序访问节点,通过顺序访问节点,可保留元素插入顺序。
import java.util.LinkedHashSet;
public class TestLinkedHashSet {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<String>();
set.add("A");
set.add("B");
set.add("C");
set.add("D");
set.add("E");
for(String s:set) {
System.out.print(s+"\t");
}
System.out.println();
//底层使用LinkedHashMap(链表结构)存储,节点形式完成单独数据的保存,并可以指向下一个节点,通过顺序访问节点,通过顺序访问节点,可保留元素插入顺序。
LinkedHashSet<Integer> nums = new LinkedHashSet<Integer>();//按插入顺序排序
System.out.println(nums.add(22));
nums.add(33);
nums.add(44);
nums.add(55);
nums.add(77);
nums.add(88);
nums.add(99);
nums.add(66);
System.out.println(nums.add(22));//false
for(Integer i:nums) {
System.out.print(i+"\t");
}
System.out.println();
}
}
- TreeSet:
基于排列顺序实现元素不重复。
实现了SortedSet接口,对集合元素自动排序。
元素对象的类型必须实现Comparable接口,指定排序规则。
通过覆盖ComparaTo方式确定是否为重复元素。根据compareTo方法返回0作为去重的依据。(意味重复)
import java.util.TreeSet;
public class TestTreeSet {
public static void main(String[] args) {
TreeSet<Integer> nums = new TreeSet<Integer>();//自动排序,调用一组对象的compareTo方法
//去重时且排序
nums.add(1);
nums.add(4);
nums.add(2);
nums.add(5);
nums.add(3);
System.out.println(nums.add(3));//保证元素不重复(唯一)
for(Integer i:nums) {
System.out.print(i+"\t");
}
System.out.println();
}
}
import java.util.TreeSet;
public class TestTreeSet2 {
public static void main(String[] args) {
TreeSet<Student> students = new TreeSet<Student>();
students.add(new Student("tom",20,"male",99.0));
students.add(new Student("jack",22,"male",100.0));
students.add(new Student("annie",19,"male",98.0));
students.add(new Student("marry",21,"male",96.0));
System.out.println(students.size());
for(Student s:students) {
System.out.println(s.name);
}
}
}
class Student implements Comparable<Student>{
String name;
Integer age;
String sex;
Double score;
public Student(String name, Integer age, String sex, Double score) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.score = score;
}
@Override
public int compareTo(Student o) {
System.out.println("compareTo被方法回调");
if(this.score < o.score) {//主要排序 this小,this靠前
return -1;
}else if(this.score > o.score) {//this大,this靠后
return 1;
}
return 0;//成绩相同//去重依据 此时这里可再用次要排序,比另一个属性利用if
}
}
Map体系集合
- Map结构
Map接口的特点:
- 用于存储任意键值对(Key—Value)
- 键:无序、无下标、不允许重复(唯一)
- 值:无序、无下标、允许重复
Map父接口
- 特点:存储一对数据(Key—Value),无序、无下标,键不可重复,值可重复。
- 方法:
V put(K key,V value)//将对象存入到集合中,关联键值。key重复则覆盖原值。
Object get(Object key)//根据键获取对应的值。
Set<K’>//返回所有key。
Collection<V’>values()//返回包含所有值的Collection集合。
Set<Map.Entry<K,V>>//键值匹配的Set集合。
Map集合的实现类
- HashMap【重点】:
-JDK1.2版本,线程不安全,运行效率快,允许用null作为key或value
HashMap算法:拿到任何一个对象,通过hash(key)做运算,key>>>16(除以16),只可能得到0~15之间的一个数组,作为插入数组的下标
HashSet中的存储便是用了HashMap存储,利用了其key,Value值则为null。
import java.util.HashMap;
public class TestBasicHashMap {
public static void main(String[] args) {
/*HashMap<Integer,String> map = new HashMap<Integer,String>();
map.put(1,"中国");
map.put(2,"美国");
map.put(3,"韩国");
map.put(5,"日本");
map.put(1,"意大利");//重复会进行键值的覆盖
String country = map.get(1);
System.out.println(country);*/
HashMap<String,String> map = new HashMap<String,String>();
map.put("CN","中国");
map.put("US","美国");
map.put("KR","韩国");
map.put("JP","日本");
map.put("IT","意大利");
map.remove("JP");
String country = map.get("CN");//调用get<Key>--通过‘CN’计算哈希,得到3,3这个下标上对比有没有CN这个key,如果有,把对应的value返回
System.out.println(country);
System.out.println(map);
}
}
import java.util.HashMap;
import java.util.Map;
public class TestHashMap {
public static void main(String[] args) {
Map<String,Student> students = new HashMap<String,Student>();
students.put("aaa",new Student());
}
}
class Student{}
Map的遍历三种方式:keySet() Values() entrySet()
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapApply {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("CN","中国");
map.put("US","美国");
map.put("KR","韩国");
map.put("JP","日本");
map.put("IT","意大利");
//1.遍历方式 keySet() 键无序、无下标,不可重复
//1.1遍历的是所有的键
Set<String> keys = map.keySet();
for(String k: keys) {
System.out.println(map.get(k));
}
//2.遍历方法 values();值 可重复
//2.1.遍历所有的值
Collection<String> cs = map.values();
for(String value:cs) {
System.out.println(value);
}
//3.entrySet();键值对
//Set集合中里存放的都是Node对象
Set<Map.Entry<String, String>> entry = map.entrySet();
for(Map.Entry<String, String> e: entry) {//JDK1.7中HashMap中的Node是entry,1.8后改为了node,接口名没变。符合接口的思想,更换实现类而不影响接口
System.out.println(e.getKey()+":"+e.getValue());//分别获取键和值
System.out.println(e);//HashMap中的Node重写了toString()方法,所以可以直接获取。
}
}
}
Hashtable
JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value
Properities
Hashtable的子类,要求key和value都是String。
通常用于配置文件的读取。在读取配置文件之后,保存文件中的键值对。反射,JDBC
import java.util.Properties;
public class TestProperties {
public static void main(String[] args) {
Properties prop = new Properties();//用于存取读取配置文件得到的键值对
//借助流读files文件中的值
prop.setProperty(key, value);
prop.getProperty(key);
}
}
TreeMap:
实现了SortedMap接口(是Map的子接口),可以对key自动排序。
TreeSet的底层,因为需要存入到TreeMap中所以需要实现Comparabble接口并去重
**泛型类型**[重点-解决应用问题]
-
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
-
特点:
编译时即可检查,而非运行时抛出异常。
访问时,不必类型转换(拆箱)。
不用泛型之间引用不能相互赋值,泛型不存在多态泛型:高级类别知识 I. 概念:约束-规范类型 II.泛型的场景:E=Element /T = Type /K = Key /V = Value 1)定义泛型 a).实例泛型: 类:创建对象时,为类所定义的泛型,进行参数化赋值 接口:实现接口时,为接口所定义的泛型,进行参数化赋值 b) .静态泛型: 定义在方法的返回值前面<T>,<T extends Objects>,<T extends Comparable<T>>,<T extends Comparable<? super T>。可应用在新参列表、返回值两种场景上,不单单可以规范泛型,还可以语义化返回值 定义在方法的形参列表当中:<?>,<? extends Object>,<? super Ineger>,不支持使用& ,只能应用在新参列表上,规范泛型
附:
集合能存各种基本类型的值,数组则需类型是一致的。数组能达到的集能达到,但集合存引用类型时,获取类的属性值后,需要向下转型由Object类转成类的类型,进而才能获取独有属性值。
在此过程中还需确保集合中对象的类型为需要的对象类型,则还需用instanceof判断Object类。
但依然无法确保new时的入口传入其他类型的对象。
即使用泛型集合。声明集合时以及引用时添加泛型。
import java.util.*;
public class TestBasicGeneric {
public static void main(String[] args) {
//1数组:元素的类型是一致的
Integer[] nums = new Integer[10];
//2集合:元素的类型可以不一致
List<Student> list = new ArrayList<Student>();
list.add(new Student("Tom",20));
//list.add(100);
for(int i = 0 ;i<list.size();i++) {
//访问学生的各个属性
//Object obj = list.get(i);
Student s = list.get(i);//省略父类引用接收返回值、省略instanceof判断类型、向下转型
//向下转型
//if(obj instanceof Student) {
//Student s = (Student)obj;
System.out.println(s.name+"\t"+s.age);
//}
}
//List<Object> numbers = new ArrayList<Integer>();//泛型不存在多态,类型才有多态
List<String> vectors = new Vector<String>();
List<Double> linkeds = new LinkedList<Double>();
}
}
class Student{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
实例泛型中的类:
public class TestInsatnceGeneric {
public static void main(String[] args) {
MyClass<Integer> mc = new MyClass<Integer>();
MyClass<Double> mc1 = new MyClass<Double>();
mc1.println(3.5);
mc.println(100);// (类)同一个方法基于实例的泛型不同,方法却可以通用
}
}
/*
* 案例1(类)
*/
class MyClass<E>{//E代表一直通配,可以任意类型,未指明类型前,为Object
public void m1(E e) {// 泛型可以动态
}
public void m2(Object o) {// 固定写死,不能变
}
//public void println(Integer i) {
// //逻辑代码相同
//}
// public void println(Double d) {
//逻辑代码相同
// }
public void println(E d) {
//逻辑代码相同
}
}
实例泛型中的接口
/*
* 实例2(接口)
*/
//E=Element /T = Type /K = Key /V = Value
interface MyInterface<T>{//实例泛型
public T method(T t);
}
class MyImplClass implements MyInterface<Dog>{//应用泛型
@Override
public Dog method(Dog t) {
return null ;
}
}
class MyImplClass2 implements MyInterface<Cat>{
@Override
public Cat method(Cat t) {
// TODO Auto-generated method stub
return null;
}
}
class Dog{
}
class Cat{
}
interface Comparable<E>{//可比较,可排序
//public int comparaTo(MyStudent s);//1.若如此,则接口耦合度高
//public int comparaTo(Object obj);//4.Object参数通用,但是具体业务场景中稍显麻烦
public int comparaTo(E obj);
}
class MyStudent implements Comparable<MyStudent>{
@Override
public int comparaTo(MyStudent s) {//2.但若改为Object obj,类型之间作比较时,需要拿到属性,而且需要向下转型,且判断类型是否为子类型
return 0;
}
}
class MyTeacher implements Comparable<MyTeacher>{
@Override
public int comparaTo(MyTeacher obj) {//3.但此时想传Myteacher
return 0;
}
}
静态泛型
import java.util.ArrayList;
import java.util.List;
public class TestStaticGeneric {
public static void main(String[] args) {
List<Dog> list1 = new ArrayList<Dog>();//约束。集合中可以存储的对象
List<Cat> list2 = new ArrayList<Cat>();
//List list = new ArrayList();//如此不建议,类型不安全,不一致
List<fish> list3 = new ArrayList<fish>();
//List<Bus> list4 = new ArrayList<Bus>();
m1(list1);
//m1(list2);//仅Dog类可以接收
m1(list2);
m1(list3);
//m1(list4);
}
//?代表任意泛型
//可接收所有动物集合
//?extends Animal泛型类型必须是Animal的子类
//?extends Comparable泛型类型必须是Comparable的实现类
//?super Dog泛型类型必须是Dog或Dog父类
public static void m1(List<? extends Animal> list) {//
}
}
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
class fish extends Animal implements Comparable<Bus> {
@Override
public int compareTo(Bus o) {
return 0;
}
}
class Bus implements Comparable<Bus>{
@Override
public int compareTo(Bus o) {
return 0;
}
}
interface comparable{
}
public class TestStaticGeneric2 {
public static void main(String[] args) {
m1(100);
m1(12.34);
//m1(true); extends Number时报错
//m1("abc");extends Number时报错
//m1(new MyNumber());//但想将其排除在外,则可看看自行定义的与number定义的区别,也就是Comparable
}
public static <T extends Number & Comparable> void m1 (T t) {//静态的泛型声明在返回值前
}
}
class MyNumber extends Number{
@Override
public int intValue() {
// TODO Auto-generated method stub
return 0;
}
@Override
public long longValue() {
// TODO Auto-generated method stub
return 0;
}
@Override
public float floatValue() {
// TODO Auto-generated method stub
return 0;
}
@Override
public double doubleValue() {
// TODO Auto-generated method stub
return 0;
}
}
import java.util.List;
import java.util.ArrayList;
public class TestStaticGeneric3 {
public static void main(String[] args) {
m(new ArrayList<Integer>());
//m(new ArrayList<Double>());Comparable<Integer>后报错
//m(new ArrayList<String>());Comparable<Integer>后报错
//m(new ArrayList<MineClass>());Comparable<T>后报错
m(new ArrayList<MineClass>());//修改了MineClass后可以运用
}
//<T extends Comparable>只要List集合中的元素,实现了Comparable接口就行
//<T extends Comparable<Integer>只要List集合中的元素,实现了Comparable接口必须是Integer泛型的
//目标:集合中的所有对象,必须具备本类型的两个元素进行比较的方法
/*public static <T extends Comparable<Integer>> void m(List<T> list) {
}*/
public static <T extends Comparable<T>> void m(List<T> list) {
//当List<T>被传入实参后,要求T所代表的类型,必须实现Comparable接口,同时接口泛型必须是T类型
}
}
class MineClass implements Comparable<MineClass>{
/*public int compareTo(Integer o) {
return 0;
}*/
@Override
public int compareTo(MineClass o) {
return 0;
}
}
import java.util.ArrayList;
import java.util.List;
public class TestStaticGeneric4 {
public static void main(String[] args) {
List<Student> students = new ArrayList<Student>();
students.add(new Student(20));
students.add(new Student(21));
students.add(new Student(19));
List<Teacher> teachers = new ArrayList<Teacher>();
teachers.add(new Teacher(20));
teachers.add(new Teacher(21));
teachers.add(new Teacher(19));
m(students);
m(teachers);
List<Person> person = new ArrayList<Person>();
person.add(new Teacher(20));
m(person);//给Person实现Comparable后报错,但其余地方报错,因为父类实现过了,子类就不能实现相同接口,因为子类已有其接口了
//去掉子类的实现接口后,m(students);m(teachers);报错。
//添加? super T后即可。
}
public static <T extends Comparable<? super T>> void m(List <T> list) {
//如果要求Comparable<T>必须是自身类型,则导致无法对一组父类引用对象进行培训,故而加入<? super T>实现接口时,无论子类和父类皆可成为泛型参数
}
}
class Student extends Person{
int age;
public Student(int age) {
super(age);
}
}
class Person implements Comparable<Person>{
int age;
public Person(int age) {
super();
this.age = age;
}
@Override
public int compareTo(Person o) {
return 0;
}
}
class Teacher extends Person{
int age;
public Teacher(int age) {
super(age);
}
}
import java.util.ArrayList;
import java.util.List;
public class TestStaticGeneric5 {
public static void main(String[] args) {
m1(new ArrayList<Integer>());
m2(new ArrayList<Integer>());
}
public static<T extends Comparable> T m1(List<T> list){
//约束返回值必须是实现了Comparable接口的类型对象
T t = (T)list.get(0);
return t;
}
public static void m2(List<? extends Comparable> list){
}
}