set接口
java.util.Set接口 extends Collection
Set接口特点
- 不允许存储重复的元素
- 没有索引,没有带索引的方法,也不能是使用普通的for循环遍历
HashSet集合
Java.util.HashSet集合 implements Set接口
- 不允许存储重复的元素
- 没有索引,没有带索引的方法,也不能是使用普通的for循环遍历
- 是一个无序的集合,存储元素和取出元素的顺序有可能不一致
- 底层是一个哈希表(查询的速度非常快)
HashSet<String> h = new HashSet<>();
h.add("1");
h.add("2");
h.add("3");
h.add("1");
//使用Iterator遍历
Iterator<String> it = h.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//使用增强for循环遍历
for (String string : h) {
System.out.println(string);
}
Hashchode
HashSet集合的存储结构(hash表)
Set集合存储元素不重复的原理
HashSet集合存储自定义类型的元素
给 HashSet 中存放自定义类型元素时,需要重写对象中的 hashCode 和 equals 方法,建立自己的比较方式,才能保证 HashSet 集合中的对象唯一
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public Person() {
super();
}
public Person(String name, int age) {
super();
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;
}
}
public class Test1 {
public static void main(String[] args) {
Person p1 = new Person("张三",20);
Person p2 = new Person("张三",20);
System.out.println(p1==p2);//false
System.out.println(p1.hashCode());//776470
System.out.println(p2.hashCode());//776470
System.out.println(p1.equals(p2));//true
}
}
LInkedHashSet 有序
Java.util.LinkedHashSet集合 extends HashSet集合
LinkedHashSet集合特点:
底层是一个哈希表(数组+链表/红黑树)+链表;多了一条链表(记录元素的存储顺序),保证元素有序
public class Test17 {
public static void main(String[] args) {
LinkedHashSet<String> l = new LinkedHashSet<>();
l.add("www");
l.add("www");
l.add("abc");
l.add("com");
System.out.println(l); //[www, abc, com] 是有序输出的
}
}
可变参数
JDK1.5出的新特新
使用前提:当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数
使用格式:定义方法时使用
修饰符 返回值类型 方法名(数据类型...变量名){}
可变参数的原理:
底层是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
传递的参数个数,可以是0个(不传递),,2,3多个
可变参数的注意事项:
- 一个方法的参数列表,只能有一个可变参
- 如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
public class Test18 {
public static void main(String[] args) {
int add = add(5,6,9);
System.out.println(add);
}
/*
* 可变你参数的终极写法
* public static int add2(Object...b){return 0;}
* */
public static int add(int...a){
int sum=0;
for (int i : a) {
sum+=i;
}
return sum;
}
}