iterator接口/泛型/装箱/拆箱/List去重

1. Iterator 接口
Iterator接口是Java集合框架的成员,主要用于遍历集合的元素(又叫迭代器)。
hasNext() 如果被迭代的集合元素还有没遍历,则返回true
next() 返回集合里的下一个元素
remove() 删除集合里上一次next方法返回的元素
原理:
当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素传给了迭代变量,而是把集合元素的值传给了迭代变量,所以修改迭代变量的值对集合元素本事没有影响。
当使用Iterator来迭代访问Collection集合元素时,Collection集合里的元素不能被修改,只能通过remove方法删除上次next方法返回的集合元素才可以,否则报java.util.ConcurrentModificationException异常(并发修改异常)。

2. 泛型
示例:
List list = new ArrayList();
//这是未引入参数化类型时的写法,list集合中可以存储不同类型的元素,如此便有了安全隐患,编译器不能保证你取值时的转型(拆箱)一定正确。
list.add(“qqyumidi”);
list.add(“corn”);
list.add(100);
list.add(true);

for (int i = 0; i < list.size(); i++) {
      String name = (String) list.get(i);
      System.out.println("name:" + name);
}

  传统集合接收和返回Object对象(不好的)
a.有装箱和拆箱操作,影响性能
b.任何类型的数据就可以接收,无法做类型控制
c.拆箱操作,即强制类型转换,带来了安全隐患,可能导致代码出异常,无法保证类型安全
d.类型转换使得代码编写更加繁琐

  2.1 泛型概念
泛型,即“参数化类型”,就是一个编译器可以自动定制作用于特定类型上的类。
简单的说就是,原本集合中用来处理的通用类型为Object,而使用了参数化类型后,编译器会自动的将Object参数的类型修改为你传递给它的参数化类型。
例如:上例运行时内存中List类中的Object属性,全被替换为String的。

作用:提高程序健壮性,简化代码
符号:T、E、K、V

  2.2 泛型接口
//定义一个泛型接口
public interface Action<T> {
    public T execute();
}

2.2.2 未传入泛型实参时:
//与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
public class UserAction<T> implements Action<T>{
    @Override
    public T execute() {
        return null;
    }
}

如果不声明泛型,编译器会报"Unknown class"异常。
public class UserAction implements Action<User>{
    @Override
    public User execute() {
        return null;
    }
}

2.2.2 传入泛型实参时
定义一个类实现这个接口,虽然我们只创建了一个泛型接口Action<T>
但是我们可以为T传入无数个实参,形成无数种类型的Action接口。
在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型

//传入泛型实参为String时
public class UserAction implements Action<String> {
    private String[] strArr = {"Apple", "Banana", "Pear"};
    @Override
    public String execute() {
        Random rand = new Random();
        return strArr[rand.nextInt(3)];
    }
}

//传入泛型实参为Integer时
public class UserAction implements Action<Integer> {
    private int[] intArr = {1,2,3,4,5,6};
    @Override
    public Integer execute() {
        Random rand = new Random();
        return intArr[rand.nextInt(3)];
    }
}

  2.3 泛型类
class 类名称 <泛型标识:可以随便写任意标识号,标识指定的泛型的类型>{
    private 泛型标识 /*(成员变量类型)*/ var; 
    .....

}

示例:创建时为类设置泛型,在实例化泛型类时,必须指定T的具体类型
public class Action<T>{
    private T key;  //key的类型为T,而T的类型由外部指定
    public Action(T key){  //构造方法key的类型也为T,T的类型由外部指定
	this.key = key;
    }
    public T getKey(){  ///getKey()的返回值类型为T,T的类型由外部指定
	return key;
    }
}

//泛型的类型参数只能是引用类型(包括自定义类),不能是值类型。
//传入的实参类型需与泛型的类型参数类型相同,即为Integer.
Action<Integer> integerAction = new Action<Integer>(123456);

//传入的实参类型需与泛型的类型参数类型相同,即为String.
Action<String> stringAction = new Action<String>("key_vlaue");

System.out.println("泛型测试", "key is " + integerAction.getKey());
System.out.println("泛型测试", "key is " + stringAction.getKey());

  2.4 泛型方法

//首先在public与返回值之间的<T>必不可少,这表明这是一个泛型方法,并且声明了一个泛型T
public <T> T showKeyName(Action<T> action){
       System.out.println("Action key :" + action.getKey());
       //当然这个例子举的不太合适,只是为了说明泛型方法的特性。
       T test = action.getKey();
       return test;
}

 2.5 泛型通配符 ?
public class Test {
    public static void main(String[] args) {
	List<String> name = new ArrayList<String>();
	List<Integer> age = new ArrayList<Integer>();
	List<Number> number = new ArrayList<Number>();
    
	name.add("icon");
	age.add(18);
	number.add(314);
	//这里传入的参数类型即有String、Int…
	getData(name);
	getData(age);
	getData(number);
    }

    //此处"?"是类型实参,而不是类型形参
    //可以把"?"看成所有类型的父类。是一种真实的类型
    public static void getData(List<?> data) {
	System.out.println("data :" + data.get(0));
    }
}

2.6. 总结

(1)泛型的默认值是Object。
(2)泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。
(3)泛型的好处:
        a. 类型安全
        b. 消除强制类型转换
        c. 提高性能。 

3. 装箱 与 拆箱
值类型 -> 引用类型 = 装箱
Integer a = new Integer(1);

  引用类型 -> 值类型 = 拆箱
Integer b = a + 10;

  jdk1.5之后引入了自动装箱及自动拆箱功能

4. List集合去重问题
4.1 循环list中的所有元素然后删除重复
public static List removeDuplicate(List list){
for ( int i = 0 ; i < list.size() - 1 ; i ++ ) {
for ( int j = list.size() - 1 ; j > i; j – ) {
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
return list;
}

4.2 通过HashSet踢除重复元素
public static List removeDuplicate(List list) {   
    HashSet h = new HashSet(list);   
    list.clear();   
    list.addAll(h);   
    return list;   
}

4.3 把list里的对象遍历一遍,用list.contain(),如果不存在就放入到另外一个list集合中
public static List removeDuplicate(List list){  
        List listTemp = new ArrayList();  
        for(int i=0;i<list.size();i++){  
           if(!listTemp.contains(list.get(i))){  
                listTemp.add(list.get(i));  
            }  
        }  
        return listTemp;  
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值