欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java自学-集合框架 HashSet

程序员文章站 2022-04-10 13:59:47
Java集合框架 HashSet 示例 1 : 元素不能重复 Set中的元素,不能重复 package collection; import java.util.HashSet; public class TestCollection { public static void main(String ......

java集合框架 hashset

示例 1 : 元素不能重复

set中的元素,不能重复

package collection;
  
import java.util.hashset;
  
public class testcollection {
    public static void main(string[] args) {
         
        hashset<string> names = new hashset<string>();
         
        names.add("gareen");
         
        system.out.println(names);
         
        //第二次插入同样的数据,是插不进去的,容器中只会保留一个
        names.add("gareen");
        system.out.println(names);
    }
}

示例 2 : 没有顺序

set中的元素,没有顺序。
严格的说,是没有按照元素的插入顺序排列

hashset的具体顺序,既不是按照插入顺序,也不是按照hashcode的顺序。

以下是hashset源代码中的部分注释

/**
 * it makes no guarantees as to the iteration order of the set;
 * in particular, it does not guarantee that the order will remain constant over time.
*/

不保证set的迭代顺序; 确切的说,在不同条件下,元素的顺序都有可能不一样

换句话说,同样是插入0-9到hashset中, 在jvm的不同版本中,看到的顺序都是不一样的。 所以在开发的时候,不能依赖于某种臆测的顺序,这个顺序本身是不稳定的
Java自学-集合框架 HashSet

package collection;
 
import java.util.hashset;
 
public class testcollection {
    public static void main(string[] args) {
        hashset<integer> numbers = new hashset<integer>();
 
        numbers.add(9);
        numbers.add(5);
        numbers.add(1);
 
        // set中的元素排列,不是按照插入顺序
        system.out.println(numbers);
 
    }
}

示例 3 : 遍历

set不提供get()来获取指定位置的元素
所以遍历需要用到迭代器,或者增强型for循环

package collection;
  
import java.util.hashset;
import java.util.iterator;
  
public class testcollection {
    public static void main(string[] args) {
        hashset<integer> numbers = new hashset<integer>();
         
        for (int i = 0; i < 20; i++) {
            numbers.add(i);
        }
         
        //set不提供get方法来获取指定位置的元素
        //numbers.get(0)
         
        //遍历set可以采用迭代器iterator
        for (iterator<integer> iterator = numbers.iterator(); iterator.hasnext();) {
            integer i = (integer) iterator.next();
            system.out.println(i);
        }
         
        //或者采用增强型for循环
        for (integer i : numbers) {
            system.out.println(i);
        }
         
    }
}

示例 4 : hashset和hashmap的关系

通过观察hashset的源代码,
可以发现hashset自身并没有独立的实现,而是在里面封装了一个map.
hashset是作为map的key而存在的
而value是一个命名为present的static的object对象,因为是一个类属性,所以只会有一个。

private static final object present = new object();
package collection;
 
import java.util.abstractset;
import java.util.hashmap;
import java.util.iterator;
import java.util.set;
 
public class hashset<e>
    extends abstractset<e>
    implements set<e>, cloneable, java.io.serializable
{
    //hashset里封装了一个hashmap
    private  hashmap<e,object> map;
 
    private static final object present = new object();
 
    //hashset的构造方法初始化这个hashmap
    public hashset() {
        map = new hashmap<e,object>();
    }
 
    //向hashset中增加元素,其实就是把该元素作为key,增加到map中
    //value是present,静态,final的对象,所有的hashset都使用这么同一个对象
    public boolean add(e e) {
        return map.put(e, present)==null;
    }
 
    //hashset的size就是map的size
    public int size() {
        return map.size();
    }
 
    //清空set就是清空map
    public void clear() {
        map.clear();
    }
     
    //迭代set,就是把map的键拿出来迭代
    public iterator<e> iterator() {
        return map.keyset().iterator();
    }
 
}

练习hashset

创建一个长度是100的字符串数组
使用长度是2的随机字符填充该字符串数组
统计这个字符串数组里重复的字符串有多少种
使用hashset来解决这个问题

答案 :

package collection;
 
import java.util.hashset;
 
public class testcollection {
    public static void main(string[] args) {
 
        string[] ss = new string[100];
        // 初始化
        for (int i = 0; i < ss.length; i++) {
            ss[i] = randomstring(2);
        }
        // 打印
        for (int i = 0; i < ss.length; i++) {
            system.out.print(ss[i] + " ");
            if (19 == i % 20)
                system.out.println();
        }
 
        hashset<string> result = new hashset<>();
 
        for (string s1 : ss) {
            int repeat = 0;
            for (string s2 : ss) {
                if (s1.equalsignorecase(s2)) {
                    repeat++;
                    if (2 == repeat) {
                        // 当repeat==2的时候,就找到了一个非己的重复字符串
                        result.add(s2);
                        break;
                    }
                }
            }
        }
 
        system.out.printf("总共有 %d种重复的字符串%n", result.size());
        if (result.size() != 0) {
            system.out.println("分别是:");
            for (string s : result) {
                system.out.print(s + " ");
            }
        }
    }
 
    private static string randomstring(int length) {
        string pool = "";
        for (short i = '0'; i <= '9'; i++) {
            pool += (char) i;
        }
        for (short i = 'a'; i <= 'z'; i++) {
            pool += (char) i;
        }
        for (short i = 'a'; i <= 'z'; i++) {
            pool += (char) i;
        }
        char cs[] = new char[length];
        for (int i = 0; i < cs.length; i++) {
            int index = (int) (math.random() * pool.length());
            cs[i] = pool.charat(index);
        }
        string result = new string(cs);
        return result;
    }
}