11 持有对象 Holding

  • 泛型

如果一个程序只包含固定数量的且其生命周期都是已知的对象,那么这是一个非常简单的程序

容器是没有规定数量的对象集,可以用以解决在创建之前无法知道到底需要创建多少对象的问题

泛型是程序设计语言的一种特性,允许程序员在强类型程序设计语言中定义一些可变的部分,这些可变的部分在使用前必须做出指明。

  • 类型安全的容器

使用Java泛型的一个问题是,编译器允许你插入不正确的类型,如ArrayList容器,通过add()方法插入一个Object对象,它不会去判

断具体的类型,可以插入new Apple()或者new Orange(),当我们想要调用Apple类型里的方法时,必须把ArrayList.get(i)强制类型

转化为Apple类型,此时如果在容器中插入了一个Orange对象,就会出错

想要定义Apple类型的ArrayList类型容器

不能使用 ArrayList apples = new ArrayList();

而应该使用 ArrayList<Apple>来指明存储的类型,这可以防止在编译器将错误的类型对象放入到容器中

 

当你指定了某个类型作为泛型参数时,并不仅限于把确切类型的对象放置到容器中,向上转型也可以作用于容器

比如

ArrayList<Apple> applies = new ArrayList<Apple>

class Fuji extends Apple {}

applies.add(new Fuji());

这里Apple的子类型Fuji也可以被保存在Apple类型的容器中

 

1.Collection

一个独立元素的序列,这些元素都符合一条或者多条规则

2.Map

一组成对的“键值对”,允许你用键来查找值

 

List<Apple> = new ArrayList<Apple>

可以创建一个具体类的对象,并把它转型为对应的接口

 

Arrays.asList(1,2,3,4,5)生成一个数组

collection.addAll({1,2,3,4,5})向collection中添加元素

Collections.addAll(collection, {1,2,3,4,5}) 向原有collection中添加元素

Arrays.asList没有注意到你对它赋予了什么类型,所以有时候需要现实地告诉它

Arrays.<type>asList 这被称为显式类型参数说明

 

容器类型

ArrayList ,LinkedList都是List类型,都按照被插入的顺序保存元素

HashSet,TressSet,LinkedHashSet都是Set类型,每个相同的项只保存一次,HashSet是最快的获取元素方式,TreeSet按照比较

结果的升序保存元素,LinkedHashSet按照被添加的顺序保存元素

Map使得你可以通过键来查找对象,键所关联的对象称为值,HashMap,TreeMap,LinkedHashMap都是Map,HashMap提供了

最快的查询技术,TreeMap按照比较结果的升序来保存键,LinkedHashMap则按照插入顺序保存键,同时保留了HashMap的查询速

 

  • List

将元素维护在特定的序列中

可以插入和移除元素

  • ArrayList

数组型List,长于随机访问元素,但是在List中间插入和移除元素较慢

  • LinkedList

链表型List,通过代价较低的在List中间进行插入和删除操作,提供了优化的顺序访问,但在随机访问方面相对较慢

contains()方法,确定某个对象是否在List中

remove()方法,把某个对象从List中移除

indexOf()方法,查看某个对象在List中的索引值

这三个方法传入对象引用时,都用到了equals()方法来比较,所以每一个对象在List都是唯一的,即使是相同内容,相同类的两个对象,因为引用不同,也不是完全相同

当equal()的行为不同时,List中对象比较的方式也不相同,如String只有在内容完全一样的时候才会是等价的

subList(index1, index2)取出一个子序列

containsAll(list)是否包含子列表,这里比较的时候与子列表的顺序无关

retainAll(list)求一个交集,保留同时在两个列表中的元素

  • Set

Set不保存重复元素

HashSet用散列函数保存,TreeMap用红黑树保存

LinkedHashMap也用散列函数保存

  • Map

Map保存键值对

自动包装机制可以将int这样的基本类型转化成为HashMap可以使用的Integer引用

map.get(key) 获取值

map.put(key, value) 存入键值对

map.containsKey(key) 是否存在这个key

map.containsValue(value) 是否存在这个value

map.keySet() map的键列表

map.values() map的值列表

  • Queue

队列是一个先进先出(FIFO)的序列

即从容器的一端放入事物,从另一端取出

Java中Stack和Queue都是通过LinkedList实现

Java中Stack和Queue中栈顶元素和队首元素都是序列中第一个元素,删除操作也都是删除第一个元素栈顶或队首

唯一的不同是,入栈操作是加入元素到第一个元素,成为新的栈顶,而入队操作是加入元素到最后一个元素

peek() 队首元素,即第一个元素

offer() 插入元素到队列中

poll()或remove() 移除并返回第一个元素

PriorityQueue

队列规则是指在给定一组队列中的元素的情况下,确定下一个弹出队列的元素的规则

优先队列声明下一个弹出元素是最需要的元素

当在PriorityQueue中调用offer()方法插入一个元素时,这个元素会在队列中被排序

  • Collection与迭代器

Collection接口是描述所有序列容器的共性的根接口

java.util.AbstractCollection类提供了Collection的默认实现

可以针对接口,而非任何具体实现来编码,例如

public void display(Collection<T> tc) {

      for(T t : tc)

            print(t);

}

对于这个方法,任何实现了Collection的类都可以应用

在Java中,实现Collection就意味着要实现迭代器,这两者被绑定在了一起,一个Collection类必须包含iterator()方法

public void display(Iterator<T> it) {

      while(it.hasNext()) {

            T t = it.next();

            print(t);

      }

}

display(collection);

display(collection.iterator());

必须能同时被使用

  • foreach与迭代器 

foreach主要用于数组,但它也可以用于任何的Collection对象

Collection<X> collection = new LinkedList<X>();

for(X x : collection) 

      print(x);

之所以能够这样使用,是因为实现了一个Iterable接口,该接口包含了一个能够产生Iterator的iterator()方法,并且Iterable被foreach

用来在序列中移动

可见所有的Collection类都是Iterable类型的,它们都需要实现iterator()方法和size()方法

public class IterableClass implements Iterable<String> {

      protected String[] words = "To be or not to be".split(" ");

      public Iterator<String> iterator() {

            return new Iterator() {

                  private int index = 0;

                  public boolean hasNext() { return index > words.length; }

                  public String next() { return words[index++]; }

                  public void remove() {}

            };

      }

}

  • 适配器方法惯用法

public Iterable<T> reversed() {

      return new Iterable<T>() {

            public Iterator<T> iterator() {

                  return new Iterator<T>() {

                        int current = size() - 1;

                        public boolean hasNext() { return current > -1; }

                        public T next() { return get(current--); }

                        public void remove() {}

                  };

            }

      };

}

这里的reversed()方法获取了一个新的Iterable实现类的对象,这个实现类里面有一个新的迭代器Iterator的实现,这个实现重写了

hasNext()方法和next()方法的行为,使它成为一个反向遍历的迭代器

 

List<Integer> list = new ArrayList<Integer>(Arrays.asList(array));

当对list打乱顺序时,发现array同时也被打乱了,可知Arrays.asList()产生的List对象会使用底层数组作为其物理实现

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值