JAVAEE细细看 进阶 08 - 集合、HashSet、LinkedHashSet

1 篇文章 0 订阅
1 篇文章 0 订阅

集合、HashSet、LinkedHashSet

一. 概述

是个接口,继承自Collection接口,所以它的内容上一文已经讲过了
特点:
a. 不包含重复元素
b. 没有带索引的方法,所以不能使用普通for遍历

练习
存储字符串并遍历

//Set 集合
Set<String> set = new HashSet<>();  // 不能保存迭代顺序
set.add("hello");
set.add("world");
set.add("java");

// 测试
set.add("world");
System.out.println(set);
System.out.println("--------");

// 遍历 迭代器
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
    String s = iterator.next();
    System.out.println(s);
}
System.out.println("--------");

// 遍历 超级for
for (String s: set) {
    System.out.println(s);
}

二. 哈希值

是jdk通过对象的地址或者字符串或者数字算出来的 int类型 的数值
Object类有一个方法,可以获取 对象的哈希值
public int hashCode() ;
在这里插入图片描述

二. HashSet集合的特点:

a. 底层数据结构是哈希表
b. 迭代遍历是无序的
c. 没有索引,所以不能用普通for遍历,要用迭代器或者超级for循环遍历
d. 由于是Set集合,所以不包含重复元素

HashSet集合保证元素唯一性源码分析
在这里插入图片描述

三. 哈希表

在这里插入图片描述

四. 案例:
创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
要求:学生对象的成员变量值相同,我们就认为是同一个对象

重点:重写系统的 equals() 和hashCode() 方法即可(直接右键创建,搞定)

// 创建HashSet对象
HashSet<Student> hs = new HashSet<>();

// 创建学生对象
Student s1 = new Student("zhangsan",8);
Student s2 = new Student("lisi",8);
Student s3 = new Student("wangwu",8);
Student s4 = new Student("zhangsan",8);

// 放到数组中
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);

// 遍历
for (Student s: hs) {
    System.out.println(s);
}

五. LinkedHashSet 集合

特点:
a. 哈希表和链表实现Set接口,具有可预测的迭代次序
b. 链表保证元素有序
c. 哈希表保证元素唯一

六. TreeSet 集合

特点:
a. 可以按一定规则排序,取决于构造方法
TreeSet(): 根据其元素的自然排序进行排序(从小到大)
TreeSetComparator: 根据比较器排序
b. 没有带索引的方法,所以不能用for循环遍历
c. 由于是Set集合,所有不包含重复的元素

自然排序 (从小到大)

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

tr.add(100); //自动装箱
tr.add(10);
tr.add(20);
tr.add(50);
tr.add(30);
tr.add(60);
tr.add(90);

for (Integer i: tr) {
    System.out.println(i); // 10 20 30 50 60 90 100
}

TreeSet Comparable的使用
案例:
存储学生对象并遍历,按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

用无参的构造器

测试类
TreeSet<Student> tr = new TreeSet<>();

Student s1 = new Student("zhansan",8);
Student s2 = new Student("lisi",8);
Student s3 = new Student("wangwu",9);
Student s4 = new Student("zhaoliu",81);
Student s5 = new Student("limei",12);
Student s6 = new Student("xiana",18);
Student s7 = new Student("xirui",7);

tr.add(s1);
tr.add(s2);
tr.add(s3);
tr.add(s4);
tr.add(s5);
tr.add(s6);
tr.add(s7);

for (Student s: tr) {
    System.out.println(s);
}

student类
@Override
public int compareTo(Object o) {
    Student s = (Student)o;
  //  return 0; // 表示两个对象相同
  //  return 1; // 正着输出,第二个对象大于第一个
  //  return -1;  // 倒着输出

    int num;

    if (this.age == s.age) {
        num = this.name.compareTo(s.name);
    } else {
        num = this.age - s.age;
    }

    return num;
}

用带参的构造器

// 用内部类
TreeSet<Student> tr = new TreeSet<>(new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        if (o1.getAge() != o2.getAge()) {
            return o1.getAge() - o2.getAge();
        } else {
            int num = o1.getName().compareTo(o2.getName());
            return num;
        }
    }
});
// 下面省略…

七. 泛型

格式:
a. <类型>
b. <类型1, 类型2 …>
c. 必须是引用类型

好处:
a. 把运行时期的问题,提前到了编译期
b. 避免了强制类型转换

Collection<String> col = new Collection<>(); 
// 在这里标记了String,后面  add类型不匹配的(比如Integer) 就会报错
// 不写String,默认是Object, 后面要强转为String

泛型类
格式:
public class Genetic {}

public class Generic<T> {
    private T k;

    public T getK() {
        return k;
    }

    public void setK(T k) {
        this.k = k;
    }
}

泛型方法

public<T>  void show(T t) {
	sout(t);
}

泛型接口

接口类
public interface Generic<T> {
	void show(T v);
}
// 实现类
public class GenericImpl<T> implements Generic<T> {
    @Override
    public void show(T v) {
        System.out.println(v);
    }
}

八. 类型通配符

在这里插入图片描述

啥意思呀?说的这么复杂。。。
看看下面的例子就知道了,只是为了创建时多态,目前感觉还是没啥用,继续往后面看看
在这里插入图片描述

九. 可变参数

概述:
使方法的参数可变
例子
public static int sum(int… a){};

public class ArgsDemo01 {
    public static void main(String[] args) {
        System.out.println(sum(10, 20));
        System.out.println(sum(10, 20, 30));
        System.out.println(sum(10, 20, 30, 40));

        System.out.println(sum(10,20,30,40,50));
        System.out.println(sum(10,20,30,40,50,60));
        System.out.println(sum(10,20,30,40,50,60,70));

    }

    public static int sum(int b, int... a){
        int sum = b;
        for (int i: a){
            sum += i;
        }
        
        return sum;
    }
}

在这里插入图片描述

十. 总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值