set集合和list集合 都是继承collction接口 是collection两个比较重要的子接口
不允许存储重复的结果,
没有带索引的方法,不能使用普通的for循环编译
set有两个比较重要的 实现类 HashSet,:
1、哈希表结构 查询的速度快…
2、没有顺序,
3、实现是不同步的,
4、此类的 iterator 方法返回的迭代器是快速失败 的:在创建迭代器之后,如果对 set 进行修改,除非通过迭代器自身的 remove 方法,否则在任何时间以任何方式对其进行修改,Iterator 都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒将来在某个不确定时间发生任意不确定行为的风险。
package SetDemo;
import java.util.HashSet;
import java.util.Set;
public class SetHash {
public static void main(String[] args) {
HashSet<Integer> s = new HashSet<>();
s.add(1);
s.add(3);
s.add(2);
s.add(1);
System.out.println(s);//[1,2,3] 自动排序,无序集合,不能有重复的
for (Integer i : s) {
System.out.println(i);
}
}
}
哈希表
首先理解 哈希值:是一个十进制的整数右系统随机给出,就是对象的地址值是逻辑地址,不是数据实际存储的物理地址下面是hashCode的源码;
1.java中所有的对象都有一个父类Object,而Object类都有hashCode方法,也就是说java中所有的类均会有hashCode方法;
public int hashCode() { //notive调用的是本地操作系统的方法,,操作系统随机给的一个整数
int h = 0;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
if (obj != null)
h += obj.hashCode();
}
return h;
}
package SetDemo;
import java.util.HashSet;
import java.util.Set;
public class SetHash {
public static void main(String[] args) {
HashSet<String> s = new HashSet<>();
s.add("1");
s.add("3");
s.add("5");
s.add("2");
s.add("1");
System.out.println(s);//[1,2,3,5] 无序集合,不能有重复 貌似还有自动排序功能
for (String i : s) {
System.out.println(i);
}
System.out.println(s.hashCode());
System.out.println(s.toString());
}
}
哈希表结构:
1.8版本之前,哈希表等于一个:
数组(初始容量16)+链表结构。
1.8版本之后 :
数组(初始容量16)+红黑树
数组(初始容量16)+红黑树//速度快
哈希表特点:速度快
set集合不允许存储重复元素的原理;
使用hashSet()存储自定义类型;
给hashSet中存放自定义类型的元素的时候,需要重写对象的hashCode和equael方法,java定义好的类都重写了这两个方法以保证元素的不重复、唯一;
自定义一个Person类用于hashSet的数据类型
package SetDemo;
import java.util.Objects;
public class Person {
String name;
int age;
public Person() {}
public Person(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;
}
@Override
public String toString() {
return "Person{" +
"name:'" + name + '\'' +
", age:" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
执行结果
package SetDemo;
import java.util.HashSet;
public class RunMain {
public static void main(String[] args) {
HashSet<Person> set= new HashSet();
Person p1 = new Person("杰森",18);
Person p2 = new Person("杰森",18);
Person p3 = new Person("杰森",19);
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set);
}
}
//结果[Person{name:'杰森', age:18}, Person{name:'杰森', age:19}]
LinkedHash()集合
特点
数组+链表(双向有序)+红黑
记录存储顺序,有序无重复的集合(多了一层链表)
方法和hashSet一样