Java 集合Collection 学习笔记

 

一.Collection三种遍历方式

(1)普通for 平时写的for(i=0;i<n;i++)一样

(2)增强for 用来遍历数组,数组类型为什么,遍历类型就为什么 

例如:

for(Student s : list) {
                    System.out.println(s.getName()+","+s.getAge());

                }
 

(3)迭代器方法遍历

hasNext()如果迭代具有更多元素,返回true

next()返回迭代中的下一个元素

通过集合对象,获取迭代器对象

例如:

//集合对象

Collection<Student> c = new ArrayList<Student>();

//迭代器对象

Iterator<Student> it = list.iterator();

//迭代器方式
        while(it.hasNext()) {
            Student s = it.next();
            System.out.println(s.getName()+","+s.getAge());
            
        }

(4)常用方法

add() 添加,clear()清空,remove()从集合中移除指定元素,isEmpty()判断集合是否为空

二.List集合概述和特点

特点

(1)有序集合(也称为序列),可以精确控制列表中每个元素的插入位置,可以通过索引访问元素,并搜索列表中的元素。

(2)与Set集合不同,允许重复元素

(3)有序:存储和取出的元素顺序一致

常用子类  :

Arraylist(查询快,增删慢),linkedlist(查询慢,增删快);
 Arraylist 底层数据结构为数组
 linkedlist底层数据结构为链表

并发修改异常(迭代器使用问题)

按照Collection的迭代器方法会出现的异常

modCount:实际修改集合次数

expectedModCount:预期修改集合次数

调用next方法时,都会判断两者是否一致,不能一边遍历时,一边添加元素(modCount增加,但是expectedModCount未增加)

解决:

(1)通过for循环用get方法获取元素

 (2)listIterator列表迭代器

next方法使用时,modCount的值会赋值给expectedModCount;

通过List集合的listIterator()方法得到,List集合特有的迭代器

可以按照任意方向遍历,并且可以边遍历,边添加元素

hasNext()向前遍历,hasPrevious()相反方向遍历,next()下一个元素并向前移动光标,previous()上一个元素,并向后移动光标。

补充:刚开始可能不能从后遍历,因为光标在最前面,无法从后往前遍历,要先从前往后遍历一次可能才能成功。(代码第一次从后遍历失败,仅猜测)

linkedlist基本方法

getFirst()返回第一个元素,getLast()返回最后一个removeFirst()删除第一个,removeLast()删除最后一个。

三.Set集合概述和特点

特点

(1)不包含重复元素的集合

(2)没有带索引的方法,所以不能使用for循环遍历

实现类

HsahSet集合概述和特点

实现Set接口,对迭代顺序没有保证,不能在一段时间保持不边(就是输入顺序和顺出顺序可能对不上)

哈希值

JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

hashCode()可以返回对象的哈希码值

同一个对象多次调用hashCode的哈希值是相同的

即使对象的内容相同,哈希值也不同

例如:

public class HashDemo {
/*
 * 哈希值是jdk根据对象的地址或字符串过着数字算出来的int类型的数值
 * hashCode()返回对象的哈希码值
 */
    public static void main(String[] args) {
        // TODO 自动生成的方法存根

        Student s1 = new Student("林青霞",30);
        System.out.println(s1.hashCode());
        System.out.println(s1.hashCode());
        //同一个对象多次调用hashCode的哈希值是相同的
        Student s2 = new Student("林青霞",30);
        System.out.println(s2.hashCode());
        //默认情况下(Object中的hashCode),不同对象的哈希值是不同的,重写hashCode
        //通过重写hashCode可以实现不同对象哈希值是相同的
        System.out.println("重地".hashCode());
        System.out.println("通话".hashCode());
        //字符串重写hashCode方法,这两个很特别
    }

}

对象类中重写hashCode和equals方法,直接生成即可

@Override
    public int hashCode() {
        return Objects.hash(age, name);
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        return age == other.age && Objects.equals(name, other.name);
    }

HashSet集合概括和特点

(1)底层数据结构是哈希表

(2)对集合的迭代顺序不作任何保证

(3)没有带索引的方法,所以不能使用for循环遍历

(4)由于是Set集合,所以不包含重复元素的集合

HashSet集合保证元素唯一性,添加一个元素的过程

HashSet存储元素时:

要保证唯一性,需要重写hashCode和equals

LinkedHashSet集合概述和特点

(1)哈希表和链表实现的Set接口,具有可预测的迭代次序

(2)由链表保证元素有序(就是输入顺序和输出顺序一样)

(3)由哈希表保证元素唯一(也就是没有重复元素)

TreeSet集合概述和特点

间接实现Set,基本类型要使用引用类型,会自动装箱,拆箱

(1)元素有序:不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决与构造方法

TreeSet():根据其元素的自然排序进行排序(从小到大)

TreeSet(Comparator comparator):根据指定的比较器进行排序

(2)没有带索引的方法,所以不能使用普通for循环遍历

(3)由于是Set集合,没有重复元素

 自然排序Co'm'pa'rable的使用

(1)用TreeSet集合存储自定义对象无参构造方法是自然排序对元素进行排序的

(2)元素所属的类要实现Co'm'pa'rable接口,重写co'm'pa'reTo(T o)方法

(3)重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

TreeSet<Integer> ts = new TreeSet<Integer>();

public int compareTo(Student s) {
        //return 0 相同
        //return 1 (正数)升序
        //return -1(负数) 降序
        //按照年龄从小到大排序
        int num = this.age-s.age;//this 相当于s2,s相当于s1
        //升序this再前,降序this在后
        int num2 = num==0?this.name.compareTo(s.name):num;
        return num2;
    }

带参构造方法,指定比较器

(1)用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的

(2)比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T O2)方法

(3)重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {//就是个内部类
    @Override
    public int compare(Student s1, Student s2) {
        //int num =  (s2.getChinese()+s2.getMath())-(s1.getChinese()+s1.getMath())
        //主要条件
        int num = s2.getSum() - s1.getSum();
        //次要条件
        int num2 = num==0?s1.getChinese()-s2.getChinese():num;
        int num3 = num2==0?s1.getName().compareTo(s2.getName()):num2;
        return num3;
    }
});
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

常态-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值