day12
一、Collectioni集合框架
集合是Java提供的一种容器,可以用来储存多个数据。
集合与数组的区别:
1.数组长度固定,集合长度可变。
2.数组储存的是同一类型的元素,可以储存基本数据类型。集合储存的是对象。而且对象的类型可以不一致。在开发中一般对象多的时候使用集合进行存储。
Collection是所有单列集合的父接口
因此在Collection中定义了单列集合(list和set)通用的方法可用于操作所有的单列集合。
add(); clear(); remove(); contains(); isEmpty(); size(); toArray(); * `public boolean add(E e)`: 把给定的对象添加到当前集合中 。 * `public void clear()` :清空集合中所有的元素。 * `public boolean remove(E e)`: 把给定的对象在当前集合中删除。 * `public boolean contains(E e)`: 判断当前集合中是否包含给定的对象。 * `public boolean isEmpty()`: 判断当前集合是否为空。 * `public int size()`: 返回集合中元素的个数。 * `public Object[] toArray()`: 把集合中的元素,存储到数组中。
二、iterator接口
iterator主要用于迭代访问(即遍历)。
Iterator接口的常用方法如下: * `public E next()`:返回迭代的下一个元素。 * `public boolean hasNext()`:如果仍有元素可以迭代,则返回 true。 Collection<String> coll = new ArrayList<String>(); // 添加元素到集合 coll.add("串串星人"); coll.add("吐槽星人"); coll.add("汪星人"); Iterator<String> it = coll.iterator(); // 泛型指的是 迭代出 元素的数据类型 while(it.hasNext()){ //判断是否有迭代元素 String s = it.next();//获取迭代出的元素 System.out.println(s);
三、泛型
我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。
> tips:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
泛型带来了哪些好处呢?
* 将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
* 避免了类型强转的麻烦。
> tips:泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。
使用泛型: 即什么时候确定泛型。 **在创建对象的时候确定泛型** 例如,`ArrayList<String> list = new ArrayList<String>();` 此时,变量E的值就是String类型,那么我们的类型就可以理解为: ~~~java class ArrayList<String>{ public boolean add(String e){ } public String get(int index){ } ... } ~~~ 再例如,`ArrayList<Integer> list = new ArrayList<Integer>();` 此时,变量E的值就是Integer类型,那么我们的类型就可以理解为: ~~~java class ArrayList<Integer> { public boolean add(Integer e) { } public Integer get(int index) { } ... }
使用格式:**调用方法时,确定泛型的类型**
定义格式:
~~~
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
~~~
例如,
~~~java
public class MyGenericMethod {
public <MVP> void show(MVP mvp) {
System.out.println(mvp.getClass());
}
public <MVP> MVP show2(MVP mvp) {
return mvp;
}
}
~~~
使用格式:**调用方法时,确定泛型的类型**
~~~java
public class GenericMethodDemo {
public static void main(String[] args) {
// 创建对象
MyGenericMethod mm = new MyGenericMethod();
// 演示看方法提示
mm.show("aaa");
mm.show(123);
mm.show(12.45);
}
}
~~~
含有泛型的接口 定义格式: ~~~ 修饰符 interface接口名<代表泛型的变量> { } ~~~ 例如, ~~~java public interface MyGenericInterface<E>{ public abstract void add(E e); public abstract E getE(); } ~~~ 使用格式: 1、定义类时确定泛型的类型** 例如 ~~~java public class MyImp1 implements MyGenericInterface<String> { @Override public void add(String e) { // 省略... } @Override public String getE() { return null; } } ~~~ 此时,泛型E的值就是String类型。
始终不确定泛型的类型,直到创建对象时,确定泛型的类型**
tips:泛型不存在继承关系 Collection<Object> list = new ArrayList<String>();这种是错误的。
泛型通配符
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
通配符高级使用----受限泛型
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的**上限**和**下限**。
**泛型的上限**:
* **格式**: `类型名称 <? extends 类 > 对象名称`
* **意义**: `只能接收该类型及其子类`
**泛型的下限**:
- **格式**: `类型名称 <? super 类 > 对象名称`
- **意义**: `只能接收该类型及其父类型`
比如:现已知Object类,String 类,Number类,Integer类,其中Number是Integer的父类
~~java
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement(list1);
getElement(list2);//报错
getElement(list3);
getElement(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}