集合框架

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实现类:

  1. JDK8的ArrayList,实际初始长度是0
  2. 首次添加元素时,需要实际分配数组空间,执行数组扩容操作
  3. 真正向数组中插入数据,用的时候再创建,或再加载,有效的减低无用内存的空间。
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结构

Alt
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){
		
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值