第11章 持有对象

持有对象

11.1 泛型和类型安全的容器

tips:

  1. 如果一个类没有显式的声明继承自哪个类,那么它自动地继承自Object;
  2. 泛型的作用:可以在 编译器 防止将错误类型的对象放置到容器中;
  3. 如果不需要使用每个元素的索引,可以使用foreach语法来选择List中的每个元素;

11.2 基本概念

一共可以分为两大类

  1. Collection
    a. ArrayList
    b. LinkedList
    c. Set
    d. Queue
  2. Map
    a. HashMap

11.3 添加一组元素

  1. Arrays.asList()
  2. Collection.addAll()
  3. Collections.addAll()
public class AddingGroups {
    public static void main(String[] args) {
        //首先构建一个Collection对象,并对其进行初始化
        //Arrays.asList()接受一个数组或者逗号分隔的元素列表,转换成一个List对象
        Collection<Integer> collection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
        Integer[] moreInts = {6, 7, 8, 9, 10};  //定义一个数组
        collection.addAll(Arrays.asList(moreInts)); //将一个数组转换为List对象
        //然后调用Collections.addAll()方法,接受一个Collection对象,然后用后面的参数填充这个Collection对象
        Collections.addAll(collection, 11, 12, 13, 14, 15);
        Collections.addAll(collection, moreInts);
        //看似返回一个List,实际底层是一个数组,不可以调整数组的大小
        List<Integer> list = Arrays.asList(16, 17, 18, 19, 20); //底层表示的是数组,不能调整尺寸大小
        list.set(1, 99);
        //list.add(0, 100); 报错Exception in thread "main" java.lang.UnsupportedOperationException
        for (int i = 0; i < collection.size(); i++) {
            System.out.print(((ArrayList<Integer>) collection).get(i) + " ");
        }
    }
}

11.4 容器的打印

  1. 打印数组需要使用Arrays.toString() ,否则只会打印内存地址
  2. ArrayList和LinkedList
    相同点:
    a. 两者都按照插入的顺序保存元素;
    不同点:
    a. ArrayList随机查询的速度比LinkedList快;
    b. LinkedList的随机增删元素的速度比ArrayList快;
    c. LinkedList包含的操作比ArrayList多;
  3. HashSet、TreeSet、LinkedHashSet
    相同点:
    a. 存储的元素都是唯一不可重复的;
    不同点:
    a. HashSet存储元素没有顺序,是 随机 的;
    b. TreeSet存储元素自动按照 升序排列
    c. LinkedHashSet存储元素按照 添加的顺序 排列;
  4. HashMap、TreeMap、LinkedHashMap
    相同点:
    a. Map对于每一个键,只能够存储一次,后面的会覆盖前面的;
    b. 不必指定Map的尺寸,它自己会自动地调整尺寸;
    不同点:
    a. HashMap存储元素没有顺序,是 随机的
    b. TreeMap按照比较结果的 升序 保存键;
    c. LinkedHashMap按照 插入的顺序 保存键,同时保留了HashMap的查询速度;

11.5 List

  1. contains()
    用来确定某个对象是否在列表中,没有则返回false;
  2. remove()
    想移除一个对象,可以将这个对象的引用传递给remove()方法,如果没有则返回false;
  3. indexOf()
    发现该对象在List中所处的位置,索引从0开始计数;
  4. subList()
    允许从较大的列表中创建出一个片段,区间是 左闭右开 的;
  5. containsAll()
    将4的结果应用到containsAll()中自然是true;
  6. Collections.sort()、Collections.shuffle()
    如果将4的结果进行随机排序或者按照某个规则排序,不会影响containsAll()的结果;
  7. retainAll()
    去两个集合的交集,但比较的结果取决于equals()方法是如何定义的;
  8. removeAll()
    移除参数中的所有元素,同样比较的结果取决于equals()方法是如何定义的;
  9. addAll(index, list)
    在位置index处把list插入,其余后面的元素后移,区别于Collection.addAll()只能将元素添加到List的结尾处;
  10. isEmpty()clear()
    判断list是否为空和清空整个List;
  11. toArray() ★★★★
    可以将 任意的 的Collection转换为一个数组,如果没有参数则返回Object数组,如果传递目标数据,将产生指定类型的数组,如果参数数组太小,toArray()方法将创建一个具有合适尺寸的数组;
        Object[] objects = pets.toArray();  //toArray();方法将集合变为数组
        System.out.println("22: " + objects[3]);
        //这里传递了目标类型的数据,但是数组大小开辟为0,
        Pet[] pa = pets.toArray(new Pet[0]);    //根据参数数组的类型构造数组
        //对于参数数组太小的情况,toArray()方法将创建一个具有合适尺寸的数组
        System.out.println("23: " + pa[3].id());

11.6 迭代器

  • 迭代的优势:统一了容器类的访问方式,有以下几个核心的方法:
  1. 使用方法iterator()要求容器返回一个Iterator,Iterator将准备好返回序列的第一个元素;
  2. 使用next()获得序列中的下一个元素;
  3. 使用hasNext()检查序列中是否还有元素;
  4. 使用remove()将迭代器新返回的元素删除(会改变原来的容器内容);
public class CrossContainerIteration {
    public static void main(String[] args) {
        ArrayList<Pet> pets = Pets.arrayList(8);
        LinkedList<Pet> pets1 = new LinkedList<>(pets);
        HashSet<Pet> pets2 = new HashSet<>(pets);
//        TreeSet<Pet> pets3 = new TreeSet<>(pets);	//Pet类想先实现Comparable才可以执行比较方法
        display(pets.iterator());
        display(pets1.iterator());
        display(pets2.iterator());
    }

    /**
     * 如果不用iterator那么需要定义三个display方法,参数类型分别
     * 为ArrayList<Pet>、LinkedList<Pet>、HashSet<Pet>
     * @param iterator iterator统一了容器的类型
     */
    private static void display(Iterator<Pet> iterator) {
        while (iterator.hasNext()){
            Pet p = iterator.next();
            System.out.print(p.id() + ":" + p + " ");
        }
        System.out.println();
    }
}

11.6.1 ListIterator

Iterator只能向前移动,而ListIterator可以双向移动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值