疯狂java笔记4:集合类(2)

Map

Map用于保存具有映射关系的数据

key和value对应,单向的一对一关系

key在一起组成了一个Set集合(key不可以重复,Map.keySet()返回这个集合)

大部分和Set集合是一样的

 

Properties类是Hashtable类的子类。其对象用于处理属性文件(windows下是ini文件)

 

WeakHashMap实现类,只保持key对实际对象的弱引用

 

IdentityHashMap实现类,与普通实现类不同之处是key相等是要key1=key2;(同一对象),而不是普通HashMap的equals(值相等)

 

 

操作集合的工具类Collections

可以对集合对象进行排序、查询、修改,还可以把集合对象设置为不可变、对集合对象实现同步控制等方法(都是static类方法)

 

泛型

增加泛型支持在很大程度上是为了让集合记住其元素的数据类型

泛型的使用

public class G

{

         publicstatic void  main(string[] args){

                   //创建一个只想保存字符串的List集合

                   List<String>strList=new ArrayList<String>();

                   //其实上面的语句可以简化为List<String>strList=new ArrayList<>();棱形语法

                   strList.add("泛型测试");

                   strList.add(5); //编译错误

         }

}

泛型可以定义的还有类、接口和方法(除了上面的做集合类实例化的参数)

public interface List<E>   //E只是一个类型形参

{

         //在该接口里,E可以作为类型来使用

         voidadd(E x);

         Iterator<E>iterator();

         ...

}

定义一个接口的时候指定一个类型形参,E

public interface Iterator<E>

{

         Enext();

         booleanhasNext();

         ...

}

//定义该接口时指定了两个类型参数,其形参名为K,V

public interface Map<K,V>

{

         //在该接口内K,V完全可以作为类型使用

         Set<K>keySet();

         Vput(K key,V value);

         ...

}

 

我们可以为任何类、接口增加泛型声明(并不是只有集合类才可以用)

eg:

public class Apple<T>

{

         //使用T类型参数定义实例参数

         privateT info;

         publicApple(){};

         //T类型来做参数的构造器

         publicApple(T info){

                   this.info=info;

         }

         publicvoid setInfo(T info){

                   this.info=omfo;

         }

         publicT getInfo(){

                   returnthis.info;

         }

         publicstatic void  main (String[] args){

                   //使用

                   Apple<String>a1=new Apple<>("苹果");

                   System.out.println(a1.getInfo());

                   //因为传给T参数的类型不对

                   Apple<String>a2=new Apple<>(31415926);

                   System.out.println(a2.getInfo());            

         }

}

泛型类派生子类最好要为泛型参数定型

public class A extends Apple<String>;              //如果不进行的话可能会报警

要注意:在静态方法、静态初始化块或静态变量的声明和初始化中不允许使用类型形参(类型形参是一个代指,不是一种真的类型,非静态的可以)

 

类型通配符

假如说要定义一个方法,该方法里有一个集合参数,集合形参的元素类型是不确定的

eg:

public void test(List c)

{

         for(inti=0;i<c.size;i++)

         {System.out.println(c.get(i));}

}

//上面的List是一个有泛型声明的接口,没有传入实际类型接口,会泛型警告

你不能这样

public void test(List<Object> c){...}

如果你使用

List<String> strList=newArrayList<>();

test(strList);    //会报错,List<String>对象不可以被List<Object>对象使用,没协变性

所以要使用类型通配符(解决了)

public void test(List<?> c){...}  //通配符可以设置上限如:...(List<?extends Shape> c)...

下限...(List<? super Type> c)...

带下限的通配符的语法可以方便在创建TreeSet对象时灵活地选择合适的Comparator(方便把所有的Comparator作为参数传入)

//类型参数其实也可以设置上限...(List<Textends Shape & java.io.Serializable> c)...        //&后面的是实现的接口

也可以使用泛型方法(上下限也可以用同通配符)

static <T> voidfromArrayToCollection(T[] a,Collection<T> c)          //其中的这个<T>是一个泛型方法的声明而不是返回值

{...}

与类、接口中使用泛型参数不同的是,方法(泛型方法)中的泛型参数无需显式传入实际的类型参数

泛型方法和类型通配符(如果这个参数只用一次,用类型通配符比较好)

 

你可能感兴趣的:(java,面向对象,iterator)