06 JAVA 容器

来源:互联网 发布:佳能mp288软件下载 编辑:程序博客网 时间:2024/05/20 06:06

什么破天气啊,太困了~


容器Container:数组长度确定了之后,不能再增长,只能创建一个新的数组,避免空间不足或者浪费,我们引入容器


  • java.util.Collection<E>接口定义了存取一组对象(这组对象可是同时是不同的类型,只要是Object或Object的子类都可以~对了,如果我们试图放入基本类型数据,编译器会自动打包Boxing该数据,使该数据变成对象)的方法,子接口Set和List分别定义了不同的存储方式:

1. Set,没有顺序+无重复元素(两个元素的哈希值是否equal,如果两个元素的哈希值equal就比较这两个元素本身是否equal,自定义的类要注意重写equals和hashCode方法,有些类已经重写了hashCode和equals方法,我们可以直接调用,如String类

2. List,有顺序+允许重复。ArrayList是将数组作为底层的存储空间,通过空间大小的计算(M*N)就可以找到下一个节点,而LinkedList通过next指向下一个节点(ArrayList读快改慢,而LinkedList改快读慢,因为ArrayList的每个元素都有标识,而且通过空间大小计算就方便读取,但是要删除的话就需要移动大量节点,而对于LinkedList只需要将Next指向另一个节点即可)

1)主要方法:

- int size()

- boolean isEmpty()

- void clear()

- boolean contains(Object element)

- boolean add(E element)

- boolean remove(Object element)

- Iterator iterator()

- boolean containsAll(Collection c)

- boolean addAll(Collection c)

- boolean removeAll(Collection c)

- boolean retainAll(Collection c)//交集

- Object[] toArray()//将集合转换成对象的数组

其中,使用remove、contains等方法时都需要比较对象是否相等,这会涉及到equals方法,而对于Set还需要用到hashCode方法,所以一定要注意自定义对象这两个方法的重写

Collection c<E> = new ArrayList/LinkedList/HashSet<E>(...),这样写的好处:Collection接口定义了公共方法,试想如果想要从一种存储方式转为另一种存储方式,只需要修改声明定义

import java.util.*;class Name {private String fn, ln;public Name(String fn, String ln) {this.fn = fn;this.ln = ln;}/*public String toString() {return fn+" "+ln;}public boolean equals(Object name) {if(name instanceof Name) {Name nm = (Name)name;return (fn.equals(nm.fn)&&ln.equals(nm.ln));}return super.equals(name);}public int hashCode() {return (fn+" "+ln).hashCode();}*/}public class TestCollection {public static void main(String args[]) {Collection c = new LinkedList();c.add(new Name("Lee", "An"));c.add(new Name("Chen", "Hua"));c.add(new Name("Liu", "Wei"));System.out.println(c.size());System.out.println(c);System.out.println(c.contains(new Name("Liu", "Wei")));c.remove(new Name("Chen", "Hua"));System.out.println(c);System.out.println("=============================");Collection c1 = new HashSet();c1.add(new Name("Cai", "Lin"));c1.add(new Name("Yang", "Zhi"));c1.add(new Name("Wang", "He"));System.out.println(c1.size());System.out.println(c1);System.out.println(c1.contains(new Name("Cai", "Lin")));c1.remove(new Name("Cai", "Lin"));System.out.println(c1);System.out.println("=============================");Collection c2 = new ArrayList();c2.add(1);c2.add("name");c2.add(new Name("Zhang", "Li"));System.out.println(c2.size());System.out.println(c2);}}

ArrayList al = new ArrayList();al.add(1);al.add("Str");ArrayList al1 = al;System.out.println(al1 == al); //trueal1.remove(1);System.out.println(al1 == al); //true

2)Iterator<E>接口

实现Collection接口的类都有一个iterator()方法来返回一个实现了迭代器接口的Iterator对象,我们可以利用这个对象方便的实现对容器内部元素的遍历

- boolean hasNext()//判断游标右边是否有元素

- E next()//返回右边的元素并移动到游标到下一个位置

- void remove()//删除右边左边的元素,迭代器的remove方法是迭代过程中删除元素的唯一方法,但是如果在迭代过程中采用集合的remove方法会发生异常,因为Iterator迭代时执行了锁定,别人不能动,只能自己动

ArrayListal =newArrayList();

al.add(new Name("Yu","Yun"));

Iterator<Name>i =al.iterator();

while(i.hasNext()) {

//如果Iterator没有指定泛型,除重写方法,i.next()必须强制转换成Name类型,才能调用Name里面其他方法

i.next().printName();

}


3) 增强for循环

优点是方便遍历容器,但是因为它的内部采用iterator方法,被锁住,所以不能remove和修改,而且还不好获取某下标元素

ArrayList<Name>al =new ArrayList<Name>();

al.add(new Name("Yu","Yun"));

for(Namen:al)

System.out.println(n); 


4)List提供的其他主要方法:

- Object get(int index);

- Object set(int index, Object element);//返回旧对象

- void add(int index, Object element);

- Object remove(int index);//返回被删除对象

- int indexOf(Object o);

- int lastIndexOf(Object o);

-类java.util.collections也提供了一些静态方法实现了基于List容器的一些常用算法

- void sort(List)

- void shuffle(List)//随机排序

- void reverse(List)

- void fill(List, Object)

- void copy(List dest, List src)

- int binarySearch(List, Object)

- java.lang.Comparable接口,只有一个方法public int compareTo(Object),用来确定容器中的对象的大小,所有排序的类都实现了java.lang.Comparable接口,所以自定义对象要记得重写这个方法~String类有自己的compareTo方法

import java.util.*;class Name implements Comparable<Name>{private String fn, ln;public Name(String fn, String ln) {this.fn = fn;this.ln = ln;}public String toString() {return fn+" "+ln;}public int compareTo(Name o){Name n = (Name) o;int firstCmp = fn.compareTo(n.fn);return (firstCmp!=0 ? firstCmp : ln.compareTo(n.ln));}}public class TestCollection {public static void main(String args[]) {List<Name> al = new ArrayList<Name>();al.add(new Name("Yi", "Ting"));al.add(new Name("Luo", "Qiang"));al.add(new Name("Fu", "Lei"));Collections.sort(al);System.out.println(al);}}

  • Map<K, V>接口定义了“key-value"映射对存储的方法

Map的键值不能重复,当我们需找某个value的时候,会先去比较key的哈希值,然后去对应的哈希值的散列同中比较key,key和value都是对象

主要方法:

- Object put(Object key, Object value) //返回旧value

- Object get(Object key)

- Object remove(Object key)

- boolean containKey(Object key)

- boolean containsValue(Object value)

- int size()

- boolean isEmpty()

- void putAll(Map t)

- void clear()

  • auto-boxing/unboxing 打包/解包
打包:将基础类型转换成对象
解包:将对象转换成基础类型
int i = (Integer) m1.get("key") //可能错误,因为可能返回的不是Integer对象,就算是,也要判断是否为null
  • 泛型 Generic
在定义集合的时候同时定义集合中对象的类型,可以在定义Collection或者Iterator是指定

Reference:
1. 马士兵JAVA基础视频

0 0
原创粉丝点击