内部类有一个例子,代码如下:

public class Controller {
    private List<Event> eventList = new ArrayList<Event>();
    public void addEvent(Event c){
        eventList.add(c);
    }
    public void run(){
        while(eventList.size() > 0){
            for(Event e : new ArrayList<Event>(eventList))
                if(e.ready()){
                    System.out.println(e);
                    e.action();
                    eventList.remove(e);
                }
        }
    }
}

在删除eventList里的元素时,这里是新创建一个ArrayList对象,并把原来的eventList之中的元素复制进去。这个地方为什么不直接从eventList里面删除呢,处于对这个问题的好奇,就查了一下资料
list有两个remove方法,一个是int为形参(按索引键删除),一个是Object为形参(按值删除)

测试demo如下:

public class Test {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>(); 
        list.add("xxx1"); 
        list.add("xxx2"); 
        list.add("xxx3"); 
        list.add("xxx3"); 
        list.add("xxx4"); 
        list.add("xxx5"); 
//        for (int i = list.size(); i >=0 ; i--) { 
//        if (i == 2 || i == 3) { 
//            list.remove(i); 
//            } 
//        } 
        
        for(String s : list){
            if(s.equals("xxx3")){
                list.remove(s);
                //break;
            }
        }
        
//        for(String s : new ArrayList<String>(list)){
//            if(s.equals("xxx3")){
//                list.remove(s);
//                //break;
//            }
//        }
        
//        for(String s : list){
//            if(s.equals("xxx2")){
//                list.remove(s);
//                break;
//                }
//            
//        }

        for (String str: list) { 
            System.out.println("str------------>" + str); 
        } 

    }

}

运行这段代码:

从这里看出,对list集合元素的按值删除操作应该不能改变list集合的大小,否则会报错

List<String> list = new ArrayList<String>(); 
        list.add("xxx1"); 
        list.add("xxx2"); 
        list.add("xxx3"); 
        list.add("xxx3"); 
        list.add("xxx4"); 
        list.add("xxx5"); 
        for (int i = 0; i < list.size() ; i++) { 
        if (i == 2 || i == 3) { 
            list.remove(i); 
            } 
        } 

按应用操作是可以的,运行结果如下:
str------------>xxx1
str------------>xxx2
str------------>xxx3
str------------>xxx5

顺便记录一下:

由于remove方法是根据list的下标索引区删除一个元素的,所以每次remove掉一个元素之后list的总长度就会减去1,而且List后面的元素会自动的去覆盖前一个被删除元素,如此容易出现下标越界的异常,为了解决这个问题:建议循环遍历List的时候倒叙遍历

list.add("xxx1"); 
list.add("xxx2"); 
list.add("xxx3"); 
list.add("xxx4"); 
list.add("xxx5"); 
for (int i = list.size(); i >=0 ; i--) { 
if (i == 2 || i == 3) { 
    list.remove(i); 
    } 
} 

 

有人在看书是提出了个问题:


在拥有外部类对象之前是不可能创建内部类对象的。创建内部类对象的时刻并不依赖于外部类的创建。说这两句话矛盾

关于这一点,知乎上有人的回答我觉得不错,顺便记录在这里

《Thinking in java》的原话是这样的: 在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗地连接到创建它的外部类对象上。但是,如果你创建的是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。 所以,除了静态内部类之外,普通的内部类都是依附于一个外部类的对象实例。某种意义上,内部类也是相当于外部类的一个“成员”。虽然不是成员字段,也不是成员方法。 另外作者也说到: 普通内部类里不能有static成员,包括嵌套类:嵌套类与普通的内部类还有一个区别。普通内部类的字段与方法,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含 因为内部类相当于外部类的一个“成员”的地位,成员的静态字段何以自处?

关于第二点,原文如下: 使用内部类,还可以获得其他一些特性: 1)内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外围类对象的信息相互独立。 2)在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。稍后就会展示一个这样的例子。 3)创建内部类对象的时刻并不依赖于外围类对象的创建。 4)内部类并没有令人迷惑的“is-a”关系;它就是一个独立的实体。 注意这里的“时刻”两个字,作者想突出内部类是外部类“轻量级的可选组件”这个特性。比如迭代器(Iterator)作为很多容器的内部类,并不是在创建容器的时候就被一起创建的。而是要我们在需要它的时候,手动创建实例,提供容器内部元素的视图。突出"optional"的特性,而不是说它本身和外部容器没关系。

 

posted on 2017-02-06 15:27  文森博客  阅读(261)  评论(0编辑  收藏  举报