Java集合(一)

Java集合的使用

Java集合(二)
Java集合(三)

一、Java集合的概念

java集合又称为java容器,主要用于在程序中存放对象,而且只能存放对象或者集合,不能存放基本数据类型。

二、容器API

J2SDK所提供的容器API位于java.util包内,集合API的类图结构如下图所示:
Java集合结构图其中,Collection集合是一个一个的往里边装,图中的“重复”指的是两个对象之间equals,Map这种容器是一对一对的往里边装。

三、Collection接口

  1. Set和List分别定义了存储方式,Set中的数据对象没有顺序且不可以重复,List中的数据对象有顺序且可以重复。
  2. Map接口定义了存储“键——值映射对”的方法
  3. Collection接口中所定义的方法:
int size//装了多少个元素或者对象
boolean isEmpty()//是否为空
void clear()//清空
boolean contains(Object element)//是否包含某个对象(包含的意思是传递的参数equals某一个内部的元素)
boolean add(Object element)//添加对象
boolean remove(Object element)//删除对象
Iterator iterator//迭代器
boolean containsAll(Collection c)//是不是包含一个集合里面的所有元素
boolean addAll(Collection c)//添加一个集合
boolean removeAll(Collection c)//删除集合
boolean retainAll(Collection c)//求当前集合类和集合c的交集
Object[] toArray()//把里面装的每个对象全部转化为一个Object类型的数组

四、equals方法和hashcode方法的重写

容器类对象在调用remove、contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和hashcode方法;对于自定义的类型,需要重写equals和hashcode方法以实现自定义的对象相等规则。

注意:相等的对象应该具有相等的hashcode,重写equals方法必须重写hashcode方法。当对象在Map里面作为一对往Map里面装,这个对一个叫“键(key)”,一个叫“值(value)”,当这个对象作为“键”的时候,hashcode是有用的。总而言之,就是重写对象的equals方法必须重写对象的hashcode方法,两个对象equals,则必须具有相同的hashcode(hash码)。
示例如下:

public class BaseContainer {

    public static void main(String[] args) {
        Collection c = new HashSet();
        c.add("hello");
        c.add(new Name("f1","l1"));
        c.add(new Integer(100));
        c.remove("hello");
        c.remove(new Integer(100));
        System.out.println(c.remove(new Name("f1","l1")));
        System.out.println(c);
    }
}

class Name{
    private String firstName;
    private String lastName;

    public Name(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Name{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }

    /**
     * 重写equals方法
     * @param obj 对象
     * @return 两个对象的比较结果,只有“我的名字”等于你传递给我的name对象的名字才返回true
     */
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Name){
            Name name = (Name) obj;
            return firstName.equals(name.firstName)
                    && lastName.equals(name.lastName);
        }
        return super.equals(obj);
    }

    /**
     * 重写hashcode方法
     * @return 暂时使用字符串的hashcode方法(也可以自己实现,但是稍微复杂,可以自己研究下)
     */
    @Override
    public int hashCode() {
        return firstName.hashCode();
    }
}

输出结果:
程序运行结果
由于String类和Integer类已经重写了equals和hashcode方法,故执行remove方法,会比较传入的对象和集合中的对象是否equals,如果equals,则将集合中的元素移除,而Name类,如果不重写equals方法和hashcode方法,则代码执行的结果如下图所示:
执行结果

五、Iterator接口

  1. 所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了iteration接口的对象。
  2. iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
  3. iterator接口定义了如下方法:
boolean hasNext();//判断游标右边是否有元素
Object next();//返回游标右边的元素并将游标移动到下一个位置
void remove();//删除游标左边的元素,在执行完next之后该操作只能执行一次
  1. iterator对象的remove方法是在迭代过程中删除元素的唯一安全的方法。
    总之,iterator就是一个统一的来遍历collection里面所有元素的方法。
    示例如下:
public class IteratorTest {
    public static void main(String[] args) {
        Collection c = new HashSet();
        c.add(new Name("f1","l1"));
        c.add(new Name("f2","l2"));
        c.add(new Name("f3","l3"));

        Iterator iterator = c.iterator();
        while (iterator.hasNext()){
            Name name = (Name) iterator.next();
            if(name.equals(new Name("f1","l1"))){
                iterator.remove();
            }

        }
        System.out.print(c);
    }
}

class Name {
    private String firstName;
    private String lastName;

    public Name(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Name{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }

    /**
     * 重写equals方法
     *
     * @param obj 对象
     * @return 两个对象的比较结果,只有“我的名字”等于你传递给我的name对象的名字才返回true
     */
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Name) {
            Name name = (Name) obj;
            return firstName.equals(name.firstName)
                    && lastName.equals(name.lastName);
        }
        return super.equals(obj);
    }

    /**
     * 重写hashcode方法
     *
     * @return 暂时使用字符串的hashcode方法(也可以自己实现,但是稍微复杂,可以自己研究下)
     */
    @Override
    public int hashCode() {
        return firstName.hashCode();
    }
}

输出结果如下:
输出结果

可以看到成功删除了名字为f1,l1的对象(因为使用的hashset集合,有可能输出的顺序和上面的不一致),需要注意的是在边遍历边删除多个集合元素过程中不能使用for循环或者增强for循环,因为在删除过程中,集合的元素个数已经发生了变化,而使用iterator可以正常删除元素,使用for循环倒序遍历也可以实现元素的删除。无论是使用哪种方式,删除一个对象都必须要重写equals方法和hashcode方法,否则无法删除元素!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值