//创建Set集合对象
Set set = new HashSet();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
//不包含重复元素 所以这里添加不进去
set.add("java");
//遍历
for ( String s : set){
System.out.println(s);
}
输出结果:
world java hello
1.2 哈希值
哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。
获取哈希值:Object中的一个方法可以返回对象的哈希值 public int hashCode():返回对象的哈希值。
HashSet集合的特点: ①该类实现Set接口,由哈希表(实际为HashMap实例)支持。 ② 对集合的迭代顺序不作任何保证; ③没有带索引的方法,所以不能使用普通for循环遍历 ④由于是Set集合,所以不包含重复元素
//创建HashSet集合
Set stringSet = new HashSet();
//存储字符串
stringSet.add("Rose");
stringSet.add("Jake");
//只能使用增强型for循环 结果不保证顺序 ,不允许重复值
for (String s : stringSet){
System.out.println(s);
}
输出结果:
Jake Rose
1.4 HashSet集合保证元素唯一性源码分析
//存储字符串
stringSet.add("Rose");
stringSet.add("Jake");
//保证元素唯一性 不添加
stringSet.add("Jake");
------------------------------------------
public class HashSet{
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
//hash值是根据元素的hashCoude()方法得到的
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node[] tab; Node p; int n, i;
//如果hash表未初始化就对hash表进行初始化
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//根据对象的hash值判断元素的存储位置,如果该位置没有元素则存储元素
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
}
public class TreeSetTest {
public static void main(String[] args) {
//创建TreeSet集合对象 基本数据引用类型要使用相对应的包装类
Set treeSet = new TreeSet<>();//使用的无参构造方法会自然排序
//存储整数
treeSet.add(10);
treeSet.add(20);
treeSet.add(22);
treeSet.add(5);
//重复元素 不会添加
treeSet.add(10);
//遍历
for (Integer o : treeSet){
System.out.println(o);
}
}
}
1.7 自然排序Comparable的使用
存储学生对象并遍历,创建集合使用无参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
注意:考察定制排序
学生类:
blic class Student implements Comparable{
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;
}
@Override
public String toString() {
return "name=" + name + " "+
"age=" + age;
}
@Override
public int compareTo(Student o) {
//return 0; //重复元素不添加
//return 1; //升序
//return -1; //降序
//按照年龄从小到大 否则按姓名字母 此this是student2的年龄
int num = this.age - o.age;
//年龄降序
//int num = o.age - this.age;
//int compareTo(To)将此对象与指定的对象进行比较以进行排序。 返回一个负整数,零或正整数,因为该对象小于,等于或大于指定对象。
int num2 = num == 0 ? this.name.compareTo(o.name) : num;
return num2;
}
}
测试类:
public class ComparableTest {
public static void main(String[] args) {
//创建TreeSet集合对象
Set studentSet = new TreeSet<>();
//创建学生对象
Student student1 = new Student("Rose",15);
Student student2 = new Student("Jake",18);
Student student3 = new Student("Pamela",22);
Student student4 = new Student("Lara",15);
Student student5 = new Student("Lara",15);
//存储学生对象
studentSet.add(student1);
studentSet.add(student2);
studentSet.add(student3);
studentSet.add(student4);
studentSet.add(student5);
//遍历集合
for (Student student : studentSet){
System.out.println(student);
}
}
}
public class NoRodeRandomTest {
public static void main(String[] args) {
//创建HashSet集合对象
Set set = new HashSet();
//创建随机数对象
Random random = new Random();
//判断集合小于10 并且产生不重复随机数
while (true){
int number = random.nextInt(20)+1;
set.add(number);
if (set.size() == 10)
break;
}
//遍历集合
for (Integer integer : set){
System.out.print(integer + " ");
}
}
}
输出结果1:
1 17 3 19 7 8 9 10 11 13
输出结果2:
17 18 2 3 19 4 5 6 9 12
TreeSet集合版本:输出结果排序,这里使用的是无参构造方法(自然排序)
public class NoRodeRandomTest {
public static void main(String[] args) {
//创建TreeSet集合对象
Set set = new TreeSet();
//创建随机数对象
Random random = new Random();
//判断集合小于10 并且产生不重复随机数
while (true){
int number = random.nextInt(20)+1;
set.add(number);
if (set.size() == 10)
break;
}
//遍历集合
for (Integer integer : set){
System.out.print(integer + " ");
}
}
}
public class GenericTest {
public static void main(String[] args) {
//类型通配符:>
List> list1 = new ArrayList
1.9.5 可变参数
可变参数又称参数可变,用作方法的形参出现,name方法参数个数就是可变的了
格式:修饰符 返回值类型 方法名(数据类型…变量名){ }
范例:public static int sum(int…a){ }
public class ArgsTest01 {
public static void main(String[] args) {
System.out.println(sum(10,20));
System.out.println(sum(20,15,4,33));
System.out.println(sum(11,12,13));
System.out.println(sum(20,30,40,50,60));
}
public static int sum(int...a){
int sum = 0;
//这里的a是一个数组
for (int i : a){
sum += i;
}
return sum;
}
}
可变参数注意事项
①这里的变量其实是一个数组
②如果一个方法有多个参数,包含可变参数,可变参数要放在最后
1.9.6 可变参数的使用
Arrays工具类中有一个静态方法:
public static List asList(T…a):返回由指定数组支持的固定大小的列表
返回的集合并不能做增删操作,可以做修改操作;
List接口中有一个静态方法:
public static List < T>List of (E…element):返回包含任意数量元素的不可变列表
返回的集合不能做增删改操作
Set接口中有一个静态方法:
public static Set of(E…elements):返回一个包含任意数量元素的不可变集合
//public static List asList(T...a):返回由指定数组支持的固定大小的列表
List list = Arrays.asList("Lisa","Jennie","Rose","Jisoo");
//会改变集合的大小 不可操作
//list.add("me"); //UnsupportedOperationException
//会改变集合的大小 不可操作
//list.remove("Lisa");
//不会改变集合长度 可操作
list.set(1,"me");
System.out.println(list);
输出结果:
[Lisa, me, Rose, Jisoo]
//public static List < T>List of (E...element):返回包含任意数量元素的不可变列表
List list = List.of("1","2",3,"2");
//会报错
// list.add("sd"); //UnsupportedOperationException
//list.remove("1");
//list.set(0,"2");
System.out.println(list);
输出结果:
[1, 2, 3, 2]
// public static Set of(E...elements):返回一个包含任意数量元素的不可变集合
Set set = Set.of("Jake", "Rose", "Jennie");
//set.add("Stark");
//set.remove("Rose");
System.out.println(set);