Java集合Set 集合、List和Collections类( 二 )

最后哈希表中的元素如下所示:
Java集合Set 集合、List和Collections类文章插图
通过上述步骤的分析 , 已经很明了的说明了 Set 集合元素不重复的原理 , 前提就是存储的元素必须重写 hashCode() 方法 和 equals() 方法 。
2.5、HashSet 集合存储自定义类型元素给 HashSet 中存放自定义类型元素时 , 需要重写对象中的hashCode() 方法和 equals() 方法 , 建立自己的比较方式 , 才能保证 HashSet 集合中的对象唯一 。 我们来看个例子 , 如下所示:
public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}public static void main(String[] args) {HashSet set = new HashSet<>();Student s1 = new Student("张三", 18);Student s2 = new Student("张三", 18);Student s3 = new Student("张三", 30);System.out.println(s1.hashCode());System.out.println(s2.hashCode());System.out.println(s3.hashCode());set.add(s1);set.add(s2);set.add(s3);System.out.println(set);}}复制代码打印结果如下所示:
Java集合Set 集合、List和Collections类文章插图
可以看到 , 如果没有重写 hashCode() 方法 和 equals() 方法 , 那么三个人是都会打印出来的 , 因为这时候他们的哈希值是不同的 。
给 Student 类重写 hashCode() 方法和 equals() 方法 , 具体如下所示:
@Overridepublic int hashCode() {return Objects.hash(name, age);}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age }复制代码打印结果如下所示:
Java集合Set 集合、List和Collections类文章插图
可以看到 , 重写了 hashCode() 方法 和 equals() 方法之后 , 就把重复的 Student 对象去掉了 。
2.6、LinkedHashSet 集合我们知道 HashSet 保证元素唯一 , 可是元素存放进去是没有顺序的 , 那么我们要保证有序 , 怎么办呢?在 HashSet 下面有一个子类 LinkedHashSet , 它是链表和哈希表组合的一个数据存储结构 , 它多了一条链表用来记录元素的存储顺序 , 所以 LinkedHashSet 是有序的 。
LinkedHashSet 集合代码演示如下所示:
public class LinkedHashSetDemo01 {public static void main(String[] args) {HashSet set = new HashSet<>();set.add("abc");set.add("www");set.add("zz");set.add("qq");set.add("it");System.out.println(set);LinkedHashSet linkedSet = new LinkedHashSet<>();linkedSet.add("abc");linkedSet.add("www");linkedSet.add("zz");linkedSet.add("qq");linkedSet.add("it");System.out.println(linkedSet);}}复制代码三、List 集合3.1、List 接口介绍List 接口继承自 Collection 接口 , 我们会将实现了 List 接口的对象称为 List 集合 。 在 List 集合中允许出现重复的元素 , 所有的元素是以一种线性的方式进行存储的 , 在程序中可以通过索引来访问集合中的指定元素 。 另外 , List 集合还有一个特点就是元素有序 , 即元素的存储和取出顺序一致 。
3.2、List 接口常用方法List 不但继承了 Collection 接口的全部方法 , 而且还增加了一些根据元素索引来操作集合的特有方法 , 如下:

  • public void add(int index, E element):将指定的元素添加到指定位置上 。
  • public E get(int index):返回集合中指定位置的元素 。
  • public E remove(int index):将指定位置上的元素移除并返回该元素 。
  • public E set(int index, E element):用指定元素替换集合中指定位置的元素 , 并返回被替换的元素 。
List 接口常用方法代码演示如下所示:
public class ListDemo01 {public static void main(String[] args) {// 创建一个 List 集合对象List list = new ArrayList<>();list.add("a");list.add("b");list.add("c");list.add("d");list.add("a");System.out.println(list);// public void add(int index, E element)// 在 c 和 d 之间添加一个 Testlist.add(3, "Test");System.out.println(list);// public E remove(int index)// 移除 c 元素String removeE = list.remove(2);System.out.println(removeE);System.out.println(list);// public E set(int index, E element)// 把最后一个 a 替换成 AString setE = list.set(4, "A");System.out.println(setE);System.out.println(list);// public E get(int index)// List 集合遍历有三种方式// 1、使用普通 for 循环for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + ", ");}System.out.println("\n");System.out.println("----------------------------分割线--------------------------");// 2、使用迭代器循环Iterator iterator = list.iterator();while (iterator.hasNext()) {System.out.print(iterator.next() + ", ");}System.out.println("\n");System.out.println("----------------------------分割线--------------------------");// 3、使用增强 for 循环for (String s : list) {System.out.print(s + ", ");}}}复制代码