黑马程序员-Java的集合类(泛型、可变参数、for-each循环和静态导入)

                    -----------android培训、java培训、java学习型技术博客、期待与您交流!------------

                           Java的集合类(泛型、可变参数、for-each循环和静态导入)

一、泛型  
    1、泛型:
       (1)JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。
       (2)在Java库中,E表示element,大多被集合框架中的类或者方法所使用元素类型;
          K和V分别表示表的键与值的类型;
          T表示type,通常普遍用在泛型类上面表示任意类型参数;还可以使用临近的字母U和S。

    2、解决问题
       (1)将运行时期出现问题ClassCastException,转移到了编译时期。
     方便于程序员解决问题。让运行时问题减少,安全。

       (2)避免了强制转换麻烦。
  

import  java.util.*;

class GenericDemo {
	public static void main(String[] args) 
	{
		//ArrayList  arr  =  new  ArrayList();
		ArrayList<String>  arr  =  new  ArrayList<String>();

		arr.add("abc0");
		arr.add("abc123");
		arr.add("abcd56");

		//arr.add(4);//当没有加类型参数时,编译正常;当添加类型参数时,编译错误.

		//方法 ArrayList.add(String)不适用
        //(参数不匹配; int无法转换为String)
        
		/*
        for(ListIterator  it = arr.listIterator();it.hasNext();){
			String   str  =  (String)it.next();//不添加类型参数时,会出现Exception in thread "main" java.lang.ClassCastException: 
			                                    //java.lang.Integer cannot be cast to java.lang.String,因为添加了4.

			System.out.println(str+"::"+str.length());
		}
		*/

		for(ListIterator<String>  it = arr.listIterator();it.hasNext();){
			String   str  =  it.next();

			System.out.println(str+"::"+str.length());
		}
	}
}


 

    3、泛型的使用:类型参数
       a、泛型格式:通过<>来定义要操作的引用数据类型。

       b、在使用java提供的对象时,通常在以下情况中要提供泛型的类型参数:
              通常在集合框架中很常见,只要见到<>就要定义泛型。其实<> 就是用来接收类型的。
          当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

          注:这是因为集合框架中的类大多是泛型类,或者提供了泛型方法,所以才可以使用泛型
      参数。

    

import java.util.*;

class LenComparator implements Comparator<String>{
	public int compare(String o1,String o2){
		int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));//互换o1和o2的位置就还可以改变集合中的顺序

		if(num==0)
			return o1.compareTo(o2);
		return num;
	}
}


class GenericDemo2 {
	public static void main(String[] args) {
		TreeSet<String> ts = new TreeSet<String>(new LenComparator());

		ts.add("abcd");
		ts.add("cc");
		ts.add("cba");
		ts.add("aaa");
		ts.add("z");
		ts.add("hahaha");

		for(Iterator<String> it = ts.iterator();it.hasNext();){
			String s = it.next();
			System.out.println(s);
		}
	}
}


 

    4、泛型类
      (1)泛型类就是具有一个或者多个类型变量的类。
      (2)什么时候定义泛型类:
               当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。
           现在定义泛型来完成扩展。

      

class Worker{

}

class Student{
}

/*
class Tool{
	private Worker w;
	public void setWorker(Worker w)
	{
		this.w = w;
	}
	public Worker getWorker()
	{
		return w;
	}
}
*/

//泛型前做法。
class Tool{
	private Object obj;
	public void setObject(Object obj){
		this.obj = obj;
	}
	public Object getObject(){
		return obj;
	}
}


//泛型类
class Utils<T>{
	private T q;
	public void setObject(T q){
		this.q = q;
	}
	public T getObject(){
		return q;
	}
}


class  GenericDemo3{
	public static void main(String[] args) {
		/*
		Tool t = new Tool();
		t.setObject(new Student());
		Worker w = (Worker)t.getObject();
		*/

		Utils<Worker> u = new Utils<Worker>();

		u.setObject(new Student());
		Worker w = u.getObject();;
	}
}


 

    5、泛型方法
       (1)泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
            为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。
      
       (2)静态方法的泛型
            静态方法不可以访问类上定义的泛型。
            如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
      
        注:泛型参数<>放在返回值的前面,修饰符的后面。

       

/*
class Demo <T>{

	public void show(T t){
		System.out.println("show::"+t);
	}

	public void print(T t){
		System.out.println("print::"+t);
	}
}
*/

class  Demo <T>{

	public void show(T t){
		System.out.println("show::"+t);
	}

	public <Q>void print(Q q){
		System.out.println("print::"+q);
	}

	//public static void method(T t){//GenericDemo4.java:24: 错误: 无法从静态上下文中引用非静态 类型变量 T
	public static <W> void method(W w){
		System.out.println("method::"+w);
	}
}





class  GenericDemo4{
	public static void main(String[] args){
        
		/*
		Demo<Integer>  d1 = new Demo<Integer>();
		d1.show(new Integer(4));
        d1.print("demo");

		Demo<String>  d2 = new Demo<String>();
		d2.show(new Integer(4));
        d2.print("demo");
		*/
       
	    Demo<String>  d3 = new Demo<String>();
		d3.show("demo");
		//d3.show(4);
		d3.print("demo print");
		d3.print(5);

		Demo.method("demo");
		Demo.method(5);
	}
}


 

     6、泛型接口

       

interface Shapes<T>{
	public void  show(T t);
}

class  MyShape implements Shapes<String>{

	public void show(String s){
		System.out.println("show::"+s);
	}

}


class MyShapePlus<T> implements Shapes<T>{
	public void show(T t){
		System.out.println("show::"+t);
	}
}


class  GenericDemo5{
	public static void main(String[] args){

		MyShape  ms  = new MyShape();
		ms.show("myshape");

		MyShapePlus<Integer>  msp  = new MyShapePlus<Integer>();
		msp.show(5);
		MyShapePlus<String>  msp1  = new MyShapePlus<String>();
		msp1.show("myshapeplus");
        
	}
}


 

     7、通配符:
        (1)?也可以理解为占位符。
    

import  java.util.*;


class  GenericDemo6{
	public static void main(String[] args){

		ArrayList<String> al = new ArrayList<String>();

		al.add("abc01");
		al.add("abc02");
		al.add("abc03");

		ArrayList<Integer> al1 = new ArrayList<Integer>();
		al1.add(4);
		al1.add(7);
		al1.add(1);

		print(al);
		print(al1);  
	}

    /*
	public static void print(ArrayList<String> al){//ArrayList<String> al = new ArrayList<Integer>();error
		
		for(Iterator<?> it = al.iterator();it.hasNext();){

			System.out.println(it.next().toString());
		}
	}
	*/
    
	//老的兼容新的
	/*
	public static void print(ArrayList al){//ArrayList al = new ArrayList<Integer>();correct,但是不严谨
		
		for(Iterator it = al.iterator();it.hasNext();){

			System.out.println(it.next().toString());
		}
	}
	*/
		
	//通配符:?
	public static void print(ArrayList<?> al){//ArrayList al = new ArrayList<Integer>();correct,但是不严谨
		
		for(Iterator<?> it = al.iterator();it.hasNext();){

			System.out.println(it.next().toString());
			System.out.println(it.next().length());//不是共有的方法,所以加上?后,一定要注意。
		}
	}
}


 

        (2)泛型的限定;
             上限:? extends E 可以接收E类型或者E的子类型。用到很多。
      

//上限:? extends E 可以接收E类型或者E的子类型。

import java.util.*;

class Person{
	private String name;
	Person(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
}

class Student extends Person{
	Student(String name){
		super(name);
	}
}

class Worker extends Person{
	Worker(String name){
		super(name);
	}
}

class  GenericDemo7{
	public static void main(String[] args) {

		System.out.println("\r\n-------------------------------\r\n");

		ArrayList<Person> arr = new	ArrayList<Person>();
		arr.add(new Person("abc01"));

		ArrayList<Student> arr1 = new ArrayList<Student>();
		arr1.add(new Student("abc02"));

		ArrayList<Worker> arr2 = new ArrayList<Worker>();
		arr2.add(new Worker("abc03"));

		arr.addAll(arr1);//public boolean addAll(Collection<? extends E> c);
		arr.addAll(arr2);

		for(Iterator<Person> it = al.iterator();it.hasNext();){
			System.out.println(it.next().getName());
		}


		System.out.println("-------------------------------");


		ArrayList<Person> al = new ArrayList<Person>();
		al.add(new Person("abc1"));
		al.add(new Person("abc2"));
		al.add(new Person("abc3"));
		print(al);


		ArrayList<Student> al1 = new ArrayList<Student>();
		al1.add(new Student("abc--1"));
		al1.add(new Student("abc--2"));
		al1.add(new Student("abc--3"));
		print(al1);  //ArrayList<Person> al = new ArrayList<Student>();error
		             //ArrayList<? extends Person> al = new ArrayList<Student>();correct

	}

	public static void print(List<? extends Person> al){
		
		for(Iterator<? extends Person> it = al.iterator();it.hasNext();)
		{
			System.out.println(it.next().getName());
		}
	}
}



             下限:? super E 可以接收E类型或者E的父类型。较少使用。
        
     

//下限:? super E 可以接收E类型或者E的父类型。

import java.util.*;

class Person{
	private String name;
	Person(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
	public String toString(){
		return "person :"+name;
	}
}

class Student extends Person{
	Student(String name){
		super(name);
	}

}

class Worker extends Person{
	Worker(String name){
		super(name);
	}
}

/*
class StuComp implements Comparator<Student>{
	public int compare(Student s1,Student s2){
		return s1.getName().compareTo(s2.getName());
	}
}

class WorkerComp implements Comparator<Worker>{
	public int compare(Worker s1,Worker s2){
		return s1.getName().compareTo(s2.getName());
	}
}
*/

class Comp implements Comparator<Person>{
	public int compare(Person p1,Person p2){
		return p1.getName().compareTo(p2.getName());//关键对比的元素要是父类有的。
	}
}

class GenericDemo8 {
	public static void main(String[] args) {
		
		TreeSet<Student> ts = new TreeSet<Student>(new Comp());//public TreeSet(Comparator<? super E> comparator)

		ts.add(new Student("abc03"));
		ts.add(new Student("abc02"));
		ts.add(new Student("abc06"));
		ts.add(new Student("abc01"));
		
		
		for(Iterator<Student> it = ts.iterator();it.hasNext();){
			System.out.println(it.next().getName());
		}

		System.out.println("-------------------------------");

		TreeSet<Worker> ts1 = new TreeSet<Worker>(new Comp());
		ts1.add(new Worker("wabc--03"));
		ts1.add(new Worker("wabc--02"));
		ts1.add(new Worker("wabc--06"));
		ts1.add(new Worker("wabc--01"));
		
		for(Iterator<Worker> it1 = ts1.iterator();it1.hasNext();){
			System.out.println(it1.next().getName());
		}
  
	}
}


 

     8、泛型总结:
            泛型的使用。
     对于集合类中的泛型会用即可。
     可以看得懂上限下限,
     泛型类和泛型方法定义。

二、可变参数

    1、JDK1.5版本出现的新特性。

    2、方法的可变参数。
       在使用时注意:可变参数一定要定义在参数列表最后面。

    3、可变参数
 其实就是上一种数组参数的简写形式。不用每一次都手动的建立数组对象。
 只要将要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。

   

class VariableParamDemo {
	public static void show(int a,int b){
		System.out.println(a+","+b);
	}	
	
	public static void show(int a,int b,int c){
		System.out.println(a+","+b+","+c);
	}

	//public static void show(int[] al){
		//for(int i=0;i<al.length;i++){
			//System.out.print(al[i]+" ");
		//}
		//System.out.println();
	//}

	public static void show(int...  arr){
		System.out.println(arr.length);
	}

	public static void show(String s,int... arr){
		System.out.println(s+","+arr.length);
	}

	public static void main(String[] args) {
		
		show(3,4);

		show(3,4,5);

		//int al[] = {3,4,5};
		//show(al);

		show(2,3,5,34,43,56);
		show();

		show("Test",34,2,12,76,98,1);
	}
}


 

三、foreach循环:高级for循环

    1、public interface Iterable<T>实现这个接口允许对象成为 "foreach" 语句的目标。


    2、格式:
 for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
 {
 }

       注:数组中是怎么实现foreach循环的。

    3、与迭代器的区别: 
       对集合进行遍历。只能获取集合元素。但是不能对集合进行操作。
       迭代器除了遍历,还可以进行remove集合中元素的动作。
       如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。


    4、传统for和高级for区别:
       高级for有一个局限性。必须有被遍历的目标。
       建议在遍历数组的时候,还是希望是用传统for。因为传统for可以定义脚标。

   

import java.util.*;

class  ForEachDemo{

	public static void generalFor() { 
		//定义一个一维数组 
		int arr[] = new int[4]; 
		System.out.println("未赋值"); 
		for (int x : arr) { 
			System.out.println(x); 
		} 

		//通过索引给数组元素赋值 
		System.out.println("赋值:索引"); 
		for (int i = 3; i > 0; i--) { 
			arr[i] = i; 
		} 

		//循环输出创建的数组 
		System.out.println("赋值后"); 
		for (int x : arr) { 
			System.out.println(x); 
		} 
	} 

	public static void main(String[] args) {


		ArrayList<String>  al  =  new ArrayList<String>();

		al.add("abc01");
		al.add("abc02");
		al.add("abc03");

		//for(Iterator it = al.iterator();it.hasNext();){
			//System.out.println(it.next());
		//}

		for(String s : al){
			s = "what?";   //只能获取集合元素。但是不能对集合进行操作。
			System.out.println(s);
		}

		System.out.println(al);

		int[] arr  = {34,56,23,98};
		for(int i:arr){
			System.out.print(i+" ");
		}

		System.out.println("------------------------------");



		//一般for可以通过角标引用元素
		generalFor();


		//Map映射中foreach
		HashMap<Integer,String>  hm  = new HashMap<Integer,String>();

		hm.put(1,"abc0");
		hm.put(2,"abc1");
		hm.put(3,"abc2");

		Set<Integer>  keyset = hm.keySet();
		for(Integer i: keyset){
			String  s  = hm.get(i);
			System.out.println(i+"::"+s);
		}

		System.out.println("------------------------------");

		//Set<Map.Entry<Integer,String>>  entryset  = hm.entrySet();
		//for(Map.Entry<Integer,String> i:entryset){
		for(Map.Entry<Integer,String> i:hm.entrySet()){
			System.out.println(i.getKey()+"--"+i.getValue());
		}



	}


}


 

四、静态导入

    (1)静态导入:一些类里面都是操作其他对象的静态方法,不需要使用对象,所以可以静态导入;

    (2)静态导入格式:import  static   类全名.*; 导入类中所有的静态成员。

    (3)当类名重名时,需要指定具体的包名。
          当方法重名是,指定具备所属的对象或者类。

    

import java.util.*;
import static  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。
import static java.util.Collections.*;

import static  java.lang.System.*;//导入了System类中所有静态成员。

class  StaticImportDemo {//extends Object
	public static void main(String[] args) {

		int[] arr = {3,1,5};

		sort(arr);
		int index = binarySearch(arr,1);
		out.println(Arrays.toString(arr));//当方法重名是,指定具备所属的对象或者类。当类名重名时,需要指定具体的包名。
		System.out.println("Index="+index);

		ArrayList<Integer> al = new ArrayList<Integer>();
		al.add(1);
		al.add(3);
		al.add(2);

		out.println(al);

		sort(al);
		out.println(al);
	}
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值