集合子接口-List以及Set

List接口

Collection接口下有两个子接口
一个是List,一个是Set
List可以储存重复的对象
列表List有一个特有的迭代器->ListIterator ListIterator() 接口,这个接口可以把集合List的元素在迭代过程中进行增删改查的行为
如:在迭代列表集合时,添加,覆盖…集合元素

List list=new ArrarList();
list.add("itcast1");
list.add("itcast2");
list.add("itcast3");


在迭代的过程中!想判断是否含有对象 itcast2 如果有那么,将其覆盖,或者在它后面加新对象

​
ListIterator it=list.ListIterator();
while(it.hasNext())
{
    Object obj=it.next();
    if("itcast2".equals(obj)
       {
           it.add("java");//如果元素中有itcast2,那么在它后面的位置添加java
           
           
           it.set("java");//如果集合中有itcast2,那么用java将其覆盖掉
           
           //这里调用的都输列表迭代器的方法
           
         
       }
}

List本身也具有方法,比如add,add(int index,Object obj),remove,get(int index)
由于List允许重复对象的存在,但是去重复对象,只保留净对象也是常用操作
去list的重复
1.创建一个新的容器,通过迭代遍历来储存筛选出来的元素
2.将原容器清空
3.将新容器的内容全部复制到原容器中

public static void getSingleElement(List list)
{
    List temp=new ArrayList();
    
    for(Iterator it=list.itrator();it.hasNext();)
    {
        Objcet obj=it.next();//不用使用集合中对象的特有方法,所以不需要向下转型
        if(!temp.contains(obj)// 集合contains方法的本质是Object的equals方法,也就是比较地址值,所以如果想要比较自己设定的对象,那么就需要重写equals方法
           {
               temp.add(obj);
           }
           list.clear;
           
           list.addAll(temp);
    } 
)
上面提到要重写equals方法
就拿学生为例,姓名和年龄相同即为重复
class Student
{
    private String name;
    private int age;
    public boolean equals(Object obj)
    {
        if(this==obj)
            return ture;
        if(!(obj instanceof Student))//尽管向上转型,但是obj对象,还是属于Student的实例
        {
            throw new ClassCastException();
        }
        Student stu=(Student) obj;
        return this.name.equals(stu.name)&&this.age==stu.age;
    }
    
    
    
}

set接口

不允许重复元素出现的集合
如果是字符串类型作为元素添加在set集合中,那么会自动去重复,如果是自己定义的对象的话呢?

Set set=new HashSet();
set.add("abc");
set.add("abc");
set.add("abcd");
set.add("abcd");
for(Iterator it=set.itretor();it.hasNext();)
{
    Object obj=it.next();
    System.out.println(obj);
}//abc,abcd

自动去重复
原理是什么呢? 是因为Set的数据结构是哈希表,也就是说,在set.add()方法调用的时候,先调用了元素对象的hashcode()方法,然后根据返回结果存入数组里,然后再equals方法来比较地址 (字符串就是比较自身内容)
就拿字符串为例,第一个abc和第二个bac的哈希值是相同的,然后比较内容,内容相同即为重复,所以数组只添加一次abc
如果是自己定义的对象呢?
同理,也是先调用对象的hashcode方法,找位置,然后再调用equals来比较,equals返回值为false,不重复,那么连在后面(链表)
所以,如果是自己定义的对象存在set里,要想去重复
要重写添加元素对象hashcode和equals方法

@override
public int hashcode()
{
    return 1;
}
public boolean equals(Object obj)
{
       if(this==obj)
                        return ture;
                    if(!(obj instanceof Student))//尽管向上转型,但是obj对象,还是属于Student的实例
                    {
                        throw new ClassCastException();
                    }
                    Student stu=(Student) obj;
                    return this.name.equals(stu.name)&&this.age==stu.age;
 }

所以你定义的对象哈希值都为1,然后就比较你定义的重复->学生的姓名与年龄,如果重复那么去掉。

但是如果重写的hashcode()返回值一直是1,
那么,先比哈希值就没有意义,因为只会在数组的某个位置,创建链表,然后根据equals()来决定是否添加。
所以,为了提高效率,应该返回特有的哈希值:

public int hashcode()
{
    return name.hashcode()+this.age;
}

Set的另一个子接口:TreeSet接口–不仅去重复,并且会自动将添加进来的元素进行排序!
TreeSet集合也会保证元素的唯一性 ,那它是怎么保证的呢???和HashSet一样吗??
不一样!!!因为数据结构不同!!

TreeSet set=new TreeSet();


​
set.add(new Student("zhangshan",21));// TreeSet的add方法,是将元素对象转成Comparable类型,就是实现接口的意思:calss Student implments Comparable//然后调用Comparable的compareTo()方法
//所以就是要重写这个方法
public int compareTo(Object obj)
{
    if(!(obj instanceof Student))
    {
        throw new ClassCastException();
    }
    Student stu=(Student)obj;
    int temp=this.age-stu.age;
    return temp==0? this.name.compareTo(stu.name):0; 
}

compareTo()如果返回值是0的话,就判定obj和this相同,然后就不会储存!!!如果结果小于0,将小的对象放在二叉树的左孩子树,将大的对象放二叉树的右孩子树,后面添加的对象,采用折中比较的方式,

来提高比较效率。(左小右大)

比较除了上面那种形式,还可以采取Comparator(比较器)的方式,在TreeSet创建对象的时候使用,而不需要在元素对象里面重写compareTo()方法:

calss CompareByName implements Comparator
{
   public int compare(Object obj1,Object obj2)//重写Comparetor的compare()方法
   {
   Student s1=(Student)obj1;
   Student s2=(Student)obj2;
   
   int temp=s1.getName().compareTo(s2.getName());//字符串默认的compareTo方法,采取相减的方式进行比较//比较姓名是第一比较因素
   
   return temp==0?s1.getAge()-s2.getAge():0;
   
}
}
​
TreeSet set=new TreeSet(new CompareByName());
set.add(new Student("woirniam",21));
set.add(new Student("wocainimo",23));

以上就是TreeSet去重复而且排序的方法!Comparetor,Comparable接口,可以用在任何地方,不仅仅是这里。
小点:Comparetor接口还有一个方法 equals () 这个只是用来判断你创建的得比较器对象是否相同,这个是Object的实例方法(抽象类可以含有实例方法但是接口只能有抽象方法),没有重写。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值