您的位置:首页 > 职场人生

黑马程序员---java集合与框架

2015-05-17 19:49 357 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

>> List

。 Set  无序、不可重复,  List  有序、可以重复 

。ArrayList 底层是一个 Object[] ,   对于 XxxList 的遍历 可以使用 迭代器,也可以使用 for   例:
List l = new ArrayList() ;    
l.add(123) ;
l.add(321) ;
l.add("kingowe") ;
l.add("kongchao") ;
for(int i=0; i<l.size(); i++)
{
  System.out.println(l.get(i) ) ;
}

。在 Arrays 工具类中有一个方法 asList(T... a) ) 可以将一个 数组转换成一个 List(ArrayList) 集合,可以方便对数组的操作,
但是不可以使用 List集合中的 增加 删除 等操作,因为数组长度是固定的, 使用了 这些方法 会 抛出异常

|--ArrayList:底层的数据结构是数组,线程不同步,ArrayList替代了Vector,查询元素的速度非常快。

|--LinkedList:底层的数据结构是链表,线程不同步,增删元素的速度非常快。

》》--》》   对 迭代器 iterator 的详解: 

package com.kingowe;

import java.util.* ;
import java.util.AbstractList.Itr;

public class CollectionTest01 {

public static void main(String[] args) {
Collection c = new ArrayList() ;
c.add(7) ;
c.add(new Float(3.14)) ;
c.add(true) ;
c.add("kingowe") ;

Iterator it = c.iterator() ; // 相当于 Iterator it = new Itr() ;
/* 迭代器的源码
* public Iterator<E> iterator() {
return new Itr();
}
*/
while( it.hasNext() )
{
System.out.println(it.next());
}
}
}

/*
* Itr 类的实现,对迭代器对象 iterator 的创建 其实是创建的 private class Itr 的实例对象
* private class Itr implements Iterator<E> {

int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount;

public boolean hasNext() {
return cursor != size();
}

public E next() {
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}

public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();

try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}

*
*/

/*
* 类关系继承图
*
* public abstract class AbstractCollection<E> implements Collection<E>
*
* public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
*
* public interface List<E> extends Collection<E>
*
* public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable

*/

。 对于 List 的实现类 有一个 ListIterator 迭代器, 它可以完成 对 List 的实现类 在迭代过程中的 增删改查 操作,
对于 Iterator 迭代器 如果在迭代过程中 对元素进行了修改 将会 抛出 CurrentModifierException, 但是使用
ListIterator 不会,ListIterator li = list.listiterator() ;

。使用 Iterator 迭代器 和 使用 ListIterator 迭代器时,在 使用它们的 next() 遍历集合中的元素的时候 指针会后移,
比如 ArrayList 集合中存放了 "孔超" "kingowe" "20", 当第一次使用 next() 后 指针会后移到 "kingowe"

》》--》》  对 contains 方法的详解

package com.kingowe;

import java.util.* ;

class Demo
{
String name ;
int no ;
public Demo(String name, int no)
{
this.name = name ;
this.no = no ;
}
}
class Person
{
String name ;
int age ;
public Person(String name, int age)
{
this.name = name ;
this.age = age ;
}
public boolean equals(Object o)
{
if(this == o)
return true ;
if(o instanceof Person)
{
Person p = (Person)o ;
if( p.name.equals(this.name) && p.age==this.age )
return true ;
}
return false ;
}
}
public class CollectionTest01 {

public static void main(String[] args) {
Collection c = new ArrayList() ; // 如果这里换成 XxxSet 以下结果将为 true false true false
// Set 无序、不可重复, List 有序、可以重复 。
Demo d1 = new Demo("kongchao", 141) ;
c.add(d1) ;
System.out.println(c.contains(d1)); // true
Demo d2 = new Demo("kongchao", 141) ;
System.out.println(c.contains(d2)); // false 在 Demo 类中没有重写 equals 方法,所以结果为 false

Person p1 = new Person("kingowe", 20) ;
c.add(p1) ;
System.out.println( c.contains(p1) ) ; // true
Person p2 = new Person("kingowe", 20) ;
System.out.println( c.contains(p2) ); // true Person类重写了 equals 方法,所以结果为 true

}
}

/* 对 contains 方法的实现
* public boolean contains(Object o) { // 在以上程序中传入的是 d1 与 d2,即为 Object o = b1, 或者 Object o = b2
return indexOf(o) >= 0;
}

public int indexOf(Object o) {
if (o == null) { // 这里 如果传入的对象引用为 null, 那么在 ArrayList中查找是否有 null这个元素,
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i])) // 这里调用了 当前传入的对象的 equals 方法, 如果该对象所属
<span style="white-space:pre"> </span> //的类没有 重写 equals 方法,则会调用 Object 中的 equals 方法
return i;
}
return -1;
}
*/

>> Set
。Set接口中的方法和Collection中方法一致的。Set接口取出方式只有一种,迭代器。

》!*!*!*!》  存储于集合中的对象都要重写 equals 方法, 存放在 HashSet 或存放在 HashMap中的key位置的对象 要重写
equals方法 和 hashCode 方法(HashMap中的key也是 Set --> 无序不可以重复)   例:

public class Employee

{

    String name ;

    String no ;

    public Employee(String name, St
4000
ring no)

    {
this.name = name ;
this.no = no ;

    }

}

Set s = new HashSet() ;
Employee e1 = new Employee("kingowe", 130141) ;
Employee e2 = new Employee("kingowe", 130141) ;
s.add(e1) ;
s.add(e2) ;
System.out.println(s.size()) ;  // 在 Employee 类 没有重写 hashCode 和 equals 方法时 输出结果为 2

解释: 因为 new 了 两个Employee 对象,虽然是同一个人,但是 HashCode 的值却不相等, 在执行 add() 方法时,会先
比较 要添加的对象的 HashCode 值 与 已经添加的对象的 hashCode 的值是否一样,如果不一样将会直接加进
该集合中,如果hashCode值与集合中已经添加的某个对象的 hashCode 的值相等,将会调用equals方法,
所以 要将 hashCode 方法 与 equals 方法重写

在本例中的 hashCode方法 的重写可以根据每个人的编号来重写,因为编号是 String 类的,且String类已经重写了
hashCode方法,所以可以  public int hashCode(){ return no.hashCode() ; }
hashCode 值 即为该对象在集合中存放的位置的索引

。 HashSet集合保证元素唯一性:通过元素的hashCode方法,和equals方法完成的。

当元素的hashCode值相同时,才继续判断元素的equals是否为true。
如果为true,那么视为相同元素,不存。如果为false,那么存储。
如果hashCode值不同,那么不判断equals,从而提高对象比较的速度。

· 对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。
· 对于HashSet集合,判断元素是否存在,或者删除元素,底层依据的是hashCode方法和equals方法。

》》--》》  TreeSet implements  SortedSet<E> 

。TreeSet集合中的元素是不可重复的,但是所有的元素会根据大小来排序,如果添加的是 基本数据类型对象,String类对象,或者 Date类
对象,那么遍历时会按大小顺序进行遍历输出, 因为这些类都实现了 Comparable 接口中的 compareTo 方法,但是如果添加的是
自定义类 而且没有实现 Cpmparable 接口 在运行时将会出现 ClassCastException

。 在向 TreeSet 集合中 add 元素的时候 会调用 compareTo 方法, 如果在实现 compareTo 方法的时候 直接 return 0 ; 那么执行 add
方法 无论 add 多少个元素 只能将第一次 add 的 对象添加进去, 因为 return 0; 表示 所添加的元素 相等,Set 不允许重复

。 TreeSet底层的数据结构就是二叉树。

package com.kingowe;

public class Demo1 {
private double price ;
public Demo1(){}
public Demo1(double price){
this.price = price ;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() { // 不要忘了Override toString 方法
return "Demo1 [price=" + price + "]";
}
}

package com.kingowe;
import java.util.Comparator;
// 专用于 Demo1 的比较器

public class Demo1Comparator implements Comparator {

/*在 java.util.Comparator 接口中定义了 两个方法:
* boolean equals(Object obj)
* int compare(T o1, T o2)
* 因为 所有类都继承自 Object, 在 Object 中已经有了 equals 方法
* 所以本类中已经有了继承自 Object类的 equals方法
* 因此 如果在该类中用不到 equals 方法,则可以只重写 compare 方法
* 如果一个非abstract类只重写了一个接口中的部分方法,那么别的方法一定
* 已经在他的 父类 中实现了
*/

@Override
public int compare(Object o1, Object o2) {
double price1 = ( (Demo1)o1 ).getPrice() ;
double price2 = ( (Demo1)o2 ).getPrice() ;
if(price1 > price2){
return 1 ;
}
else if(price1 < price2){
return -1 ;
}
else
return 0 ;
}
/*
* 注意: 在此程序中 对 double 类型的比较设计的不合理,因为double型在
* 内存中存储时是按近似值存储的,因此有可能出现 两个价格都为17.17 却不会
* 返回 0
*/
}

package com.kingowe;
import java.util.* ;

public class TreeSetTest {
public static void main(String[] args) {
// TreeSet(Comparator<? super E> comparator)
// 通过传入一个比较器来完成 add时对象之间的比较
SortedSet ss = new TreeSet(new Demo1Comparator()) ;
ss.add(new Demo1(34.5)) ;
ss.add(new Demo1(12.3)) ;
ss.add(new Demo1(67.8)) ;
ss.add(new Demo1(45.6)) ;
ss.add(new Demo1(33.4)) ;
ss.add(new Demo1(56.7)) ;
Iterator it = ss.iterator() ;
while(it.hasNext()){
System.out.println(it.next());
}
}
}


>> Map
。 存储在 Map集合 中的 key 值元素要重写 equals 方法 和 hashCode 方法,如果 key 值是String类型,则可以不重写,
因为在 String 类中已经重写了这两个方法

。 Set<K> keySet()  因为 key 值不可以重复,所以要返回 Set ,   Collection<V> values()  因为 vlaue 值可以重复,所以
要返回 Collection

。 |--Hashtable:底层是哈希表数据结构,是线程同步的。不可以存储null键,null值。
   |--HashMap:底层是哈希表数据结构,是线程不同步的。可以存储null键,null值。替代了Hashtable.

  values 方法解释: 

package com.kingowe;
import java.util.*;

public class MapTest {
public static void main(String[] args) {
Map m = new HashMap();
m.put("1000", "kingowe");
m.put("1001", "kongchao");
Collection c = m.values() ;
Iterator it = c.iterator() ;
while(it.hasNext())
{
System.out.println(it.next()) ;
}
System.out.println(c.size());
System.out.println(c.isEmpty());
}
}

java.util.HashMap 中 values() 的源码:

public Collection<V> values() {
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
}

// AbstractCollection<E>定义: public abstract class AbstractCollection<E> implements Collection<E>
// 属性 values 的声明 : transient volatile Collection<V> values = null;

// Values 内部类
private final class Values extends AbstractCollection<V> {
public Iterator<V> iterator() {
return newValueIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsValue(o);
}
public void clear() {
HashMap.this.clear();
}
}

》》--》》  遍历 Map 中的 key - value
/方法一(通常使用该方法,比较灵活):

package com.kingowe;
import java.util.*;

public class MapTest {
public static void main(String[] args) {
Map m = new HashMap();
m.put("1000", "kingowe");
m.put("1001", "kongchao");
m.put("1005", "kong");
m.put("1002", "king");
Set s = m.keySet() ; // 通过该方法获得 Map集合 中的 key值 的 Set集合
Iterator it = s.iterator() ; // 获得 set 集合的迭代器,
while(it.hasNext()) {
Object k = it.next(); // 取出 Map集合中的 key 值
Object v = m.get(k) ; // 通过得到的 key 值 来获取相对应的 value
System.out.println(k+" --> "+v); // 最后将 key - value 对输出
}
}
}方法二(不灵活,输出格式只能是 key=value):
package com.kingowe;
import java.util.*;

public class MapTest {
public static void main(String[] args) {
Map m = new HashMap();
m.put("1000", "kingowe");
m.put("1001", "kongchao");
m.put("1005", "kong");
m.put("1002", "king");
// 通过 Set entrySet() 来获取 key=value
Set s = m.entrySet() ;
Iterator it = s.iterator() ;
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 集合与框架