1.存储对象可以考虑:①数组 ②集合
2.数组存储对象的特点:Student[] stu = new Student[20]; stu[0] = new Student();....
>弊端:①一旦创建,其长度不可变。②真实的数组存放的对象的个数是不可知。
3.集合
Collection接口
|------List接口:存储有序的,可以重复的元素
|------ArrayList(主要的实现类)、LinkedList(对于频繁的插入、删除操作)、Vector(古老的实现类、线程安全的)
|------Set接口:存储无序的,不可重复的元素
|------HashSet (主要实现类)、LinkedHashSet、TreeSet
Map接口:存储“键-值”对的数据
|-----HashMap、LinkedHashMap、TreeMap、Hashtable (子类:Properties)
1. size():返回集合中元素的个数 2. add(Object obj):向集合中添加一个元素 3. addAll(Collection coll):将形参coll中包含的所有元素添加到当前集合中 4. isEmpty():判断集合是否为空 5. clear():清空集合元素 6. contains(Object obj):判断集合中是否包含指定的obj元素。如果包含,返回true,反之返回false //判断的依据:根据元素所在的类的equals()方法进行判断 // 明确:如果存入集合中的元素是自定义类的对象。要求:自定义类要重写equals()方法! 7. containsAll(Collection coll):判断当前集合中是否包含coll中所有的元素 8. retainAll(Collection coll):求当前集合与coll的共有的元素,返回给当前集合 9. remove(Object obj):删除集合中的obj元素。若删除成功,返回true。否则,返回false 10. removeAll(Collection coll):从当前集合中删除包含在coll中的元素。 11. equals(Object obj):判断集合中的所有元素是否完全相同 12. hashCode(): 13. toArray() :将集合转化为数组 14. iterator():返回一个Iterator接口实现类的对象,进而实现集合的遍历!
Java 5 提供了 foreach 循环迭代访问 Collection
//使用迭代器Iterator实现集合的遍历 Iterator i = coll.iterator(); while(i.hasNext()){ System.out.println(i.next()); }
//使用增强for循环实现集合的遍历 for(Object i:coll){ System.out.println(i); }
练习:
public void testFor3(){ String[] str = new String[]{"AA","BB","DD"}; for(String s : str){ s = "MM";//此处的s是新定义的局部变量,其值的修改不会对str本身造成影响。 System.out.println(s); } for(int i = 0;i < str.length;i++){ System.out.println(str[i]); } }
List中相对于Collection,新增加的方法
void add(int index, Object ele):在指定的索引位置index添加元素ele boolean addAll(int index, Collection eles) Object get(int index):获取指定索引的元素 Object remove(int index):删除指定索引位置的元素 Object set(int index, Object ele):设置指定索引位置的元素为ele int indexOf(Object obj):返回obj在集合中首次出现的位置。没有的话,返回-1 int lastIndexOf(Object obj):返回obj在集合中最后一次出现的位置.没有的话,返回-1 List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex结束的左闭右开一个子list List常用的方法:增(add(Object obj)) 删(remove) 改(set(int index,Object obj)) 查(get(int index)) 插(add(int index, Object ele)) 长度(size())
ArrayList 是 List 接口的典型实现类.
本质上,ArrayList是对象引用的一个变长数组.
ArrayList 是线程不安全的,而 Vector 是线程安全的,即使为保证 List 集合线程安全,也不推荐使用Vector.
Arrays.asList(…) 方法返回的 List 集合既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…) 返回值是一个固定长度的 List 集合.
对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高
新增方法:
void addFirst(Object obj) void addLast(Object obj) Object getFirst() Object getLast() Object removeFirst() Object removeLast()
Vector 是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。
在各种list中,最好把ArrayList作为缺省选择。当插入、删除频繁时,使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。
新增方法:
void addElement(Object obj) void insertElementAt(Object obj,int index) void setElementAt(Object obj,int index) void removeElement(Object obj) void removeAllElements()
一、ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历。但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
二、ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator 没有此功能。
三、ListIterator有add()方法,可以向List中插入对象,而Iterator不能。
四、都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。
Set:存储的元素是无序的,不可重复的!
1.无序性:无序性!= 随机性。真正的无序性,指的是元素在底层存储的位置是无序的。
2.不可重复性:当向Set中添加进相同的元素的时候,后面的这个不能添加进去。
Set接口是Collection的子接口,set接口没有提供额外的方法
Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法
说明:要求添加进Set中的元素所在的类,一定要重写equals()和hashCode()方法。 进而保证Set中元素的不可重复性!
HashSet 具有以下特点:
不能保证元素的排列顺序
HashSet 不是线程安全的
集合元素可以是 null
Set中的元素时如何存储的呢?使用了哈希算法。
当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值,此哈希值决定了此对象在Set中的存储位置。若此位置之前没有对象存储,则这个对象直接存储到此位置。若此位置已有对象存储,再通过equals()比较这两个对象是否相同。如果相同,后一个对象就不能再添加进来。 万一返回false呢,都存储。(不建议如此)
要求:hashCode()方法要与equals()方法一致。
LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。
1.向TreeSet中添加的元素必须是同一个类的。
2.可以按照添加进集合中的元素的指定的顺序遍历。像String,包装类等默认按照从小到大的顺序遍历。
3.当向TreeSet中添加自定义类的对象时,有两种排序方法:①自然排序 ②定制排序
4.自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)的抽象方法
在此方法中,指明按照自定义类的哪个属性进行排序。
5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的此属性值相同,但是程序会认为这两个对象是相同的,进而后一个对象就不能添加进来。
> compareTo()与hashCode()以及equals()三者保持一致!
TreeSet的定制排序: compare()与hashCode()以及equals()三者保持一致!
例子:
public void testTreeSet2() { // 1.创建一个实现了Comparator接口的类对象 Comparator com = new Comparator() { // 向TreeSet中添加Customer类的对象,在此compare()方法中,指明是按Customer // 的哪个属性排序的。 @Override public int compare(Object o1, Object o2) { if (o1 instanceof Customer && o2 instanceof Customer) { Customer c1 = (Customer) o1; Customer c2 = (Customer) o2; int i = c1.getId().compareTo(c2.getId()); if (i == 0) { return c1.getName().compareTo(c2.getName()); } return i; } return 0; } }; // 2.将此对象作为形参传递给TreeSet的构造器中 TreeSet set = new TreeSet(com); // 3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象。 set.add(new Customer("AA", 1003)); set.add(new Customer("BB", 1002)); set.add(new Customer("GG", 1004)); set.add(new Customer("CC", 1001)); set.add(new Customer("DD", 1001)); for (Object str : set) { System.out.println(str); } }
|-----HashMap:Map的主要实现类
|-----LinkedHashMap:使用链表维护添加进Map中的顺序。故遍历Map时,是按添加的顺序遍历的。
|-----TreeMap:按照添加进Map中的元素的key的指定属性进行排序。要求:key必须是同一个类的对象!
针对key:自然排序 vs 定制排序
|-----Hashtable:古老的实现类,线程安全,不建议使用。
|----Properties:常用来处理属性文件。键和值都为String类型的
Map 常用方法:
Object put(Object key,Object value):向Map中添加一个元素 Object remove(Object key):按照指定的key删除此key-value void putAll(Map t) void clear():清空 Object get(Object key):获取指定key的value值。若无此key,则返回null boolean containsKey(Object key) boolean containsValue(Object value) int size():返回集合的长度 boolean isEmpty() boolean equals(Object obj)
1.key是用Set来存放的,不可重复。value是用Collection来存放的,可重复一个key-value对,是一个Entry。所有的Entry是用Set存放的,也是不可重复的。
2.向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同。若相同 则只能添加进后添加的那个元素。
3. 允许使用null键和null值,与HashSet一样,不保证映射的顺序。
4. HashMap 判断两个 key 相等的标准是:两个 key 通过 equals() 方法返回 true,hashCode 值也相等。
5. HashMap 判断两个 value相等的标准是:两个 value 通过 equals() 方法返回 true。
Map 的遍历:
Set keySet() Collection values() Set entrySet()
public void test2() { Map map = new HashMap(); map.put("AA", 213); map.put("BB", 45); map.put(123, "CC"); map.put(null, null); map.put(new Person("DD", 23), 89); // 1.遍历key集。 Set set = map.keySet(); for (Object obj : set) { System.out.println(obj); } // 2.遍历value集 Collection values = map.values(); Iterator i = values.iterator(); while (i.hasNext()) { System.out.println(i.next()); } // 3.如何遍历key-value对。 // 方式一: Set set1 = map.keySet(); for (Object obj : set1) { System.out.println(obj + "----->" + map.get(obj)); } // 方式二: Set set2 = map.entrySet(); for (Object obj : set2) { Map.Entry entry = (Map.Entry) obj; // System.out.println(entry.getKey() + "---->" + entry.getValue()); System.out.println(entry); } }
与LinkedHashSet类似,LinkedHashMap 可以维护 Map 的迭代顺序:迭代顺序与 Key-Value 对的插入顺序一致
TreeMap 的 Key 的排序:
自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口
与HashMap不同,Hashtable 不允许使用 null 作为 key 和 value
Hashtable判断两个key相等、两个value相等的标准,与hashMap一致。
Properties 类是 Hashtable 的子类,该对象用于处理属性文件
由于属性文件里的 key、value 都是字符串类型,所以 Properties 里的 key 和 value 都是字符串类型
存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法
例子:
public void test6() throws FileNotFoundException, IOException{ Properties pros = new Properties(); pros.load(new FileInputStream(new File("jdbc.properties"))); String user = pros.getProperty("user"); System.out.println(user); String password = pros.getProperty("password"); System.out.println(password); }
Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法
//排序操作:(均为static方法) reverse(List):反转 List 中元素的顺序 shuffle(List):对 List 集合元素进行随机排序 sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序 sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序 swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
//查找、替换 Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素 Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素 Object min(Collection) Object min(Collection,Comparator) int frequency(Collection,Object):返回指定集合中指定元素的出现次数 void copy(List dest,List src):将src中的内容复制到dest中 boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
同步控制
Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题
原文:http://www.cnblogs.com/linyueshan/p/5510483.html