how2j.cn

本视频是解读性视频,所以希望您已经看过了本知识点的内容,并且编写了相应的代码之后,带着疑问来观看,这样收获才多。 不建议一开始就观看视频



7分15秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器



示例 1 : 元素不能重复   
示例 2 : 没有顺序   
示例 3 : 遍历   
示例 4 : HashSet和HashMap的关系   
示例 5 : 练习-HashSet   
示例 6 : 答案-HashSet   

示例 1 :

元素不能重复

edit
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); } }
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);
    }
}
Set中的元素,没有顺序。
严格的说,是没有按照元素的插入顺序排列

HashSet的具体顺序,既不是按照插入顺序,也不是按照hashcode的顺序。关于hashcode有专门的章节讲解: 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的不同版本中,看到的顺序都是不一样的。 所以在开发的时候,不能依赖于某种臆测的顺序,这个顺序本身是不稳定的
没有顺序
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); } }
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);

	}
}
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的关系

edit
通过观察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(); } }
示例 5 :

练习-HashSet

edit  姿势不对,事倍功半! 点击查看做练习的正确姿势
比较字符串章节,有一个同样的练习
创建一个长度是100的字符串数组
使用长度是2的随机字符填充该字符串数组
统计这个字符串数组里重复的字符串有多少种
使用HashSet来解决这个问题
练习-HashSet
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
查看本答案会花费4个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法 或者一次性购买JAVA 中级总计0个答案 (总共需要0积分)
查看本答案会花费4个积分,您目前总共有点积分。查看相同答案不会花费额外积分。 积分增加办法 或者一次性购买JAVA 中级总计0个答案 (总共需要0积分)
账号未激活 账号未激活,功能受限。 请点击激活
本视频是解读性视频,所以希望您已经看过了本答案的内容,带着疑问来观看,这样收获才多。 不建议一开始就观看视频

2分44秒 本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器


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; } }


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2025-06-18 我的答案
Zzz112138




X8 5J NB 08 9t y5 39 G7 15 Iy d3 2Z Mf 2X KX G3 Qm 30 Rq P3 Rg dp 3T g1 8l a5 7m uW c8 9Y iK wK 6e 9l zR 4g lh X7 Y6 Zv wv a5 Kn 7Z O2 aA ld Aa 3l 43 3c 1Q lP Ej IA 15 Dt 0F 2W Gj oF 9z 4N T2 8G 28 Ep SQ m2 VK 72 j9 2L 19 AI D2 q4 9F Ju 7x U3 XK 68 K7 4x 21 AZ y1 0j 28 q3 u4 VT 5m a9 19 Yg q0 7v a9 总共有5种重复的字符串 分别是: a5 15 28 19 a9
	// 获取随机字符串
	public static String getRandomStr(int length) {
		char[] cs = new char[length];
		int random = 0;
		for (int i = 0; i < length; i++) {
			random = (int) (Math.random() * 3);
			if (random == 0) {
				cs[i] = (char) ('A' + (int) (Math.random() * 26));
			} else if (random == 1) {
				cs[i] = (char) ('a' + (int) (Math.random() * 26));
			} else {
				cs[i] = (char) ('0' + (int) (Math.random() * 10));
			}
		}
		return new String(cs);
	}

	// 练习
	public static void main(String[] args) {
		String[] strs = new String[100];

		HashSet<String> hs = new HashSet<>();
		List<String> tempList = new ArrayList<>();

		for (int i = 0; i < strs.length; i++) {
			strs[i] = getRandomStr(2);
		}

		for (int i = 0; i < strs.length; i++) {
			if (i != 0 && i % 20 == 0)
				System.out.println();
			System.out.print(strs[i] + " ");
			if (hs.add(strs[i]) == false) {
				tempList.add(strs[i]);
			}
		}

		System.out.format("%n总共有%d种重复的字符串%n分别是:%n", tempList.size());
		for (Iterator<String> it = tempList.iterator(); it.hasNext();) {
			String str = it.next();
			System.out.print(str + " ");
		}
		System.out.println();

	}

							





回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2023-06-12 想了半天随机字符才弄出来的答案
tiang




用随机数强转char类型,获取随机字符,获取两个就返回,然后存起来,用for-each遍历存进hashset,
public class demo2 {
    public static void main(String[] args) {
        String arr[]=new String[100];
        ArrayList<String> tempList=new ArrayList<>();
        int count=0,flag=0;
        while (count<100){
            arr[count]=charRandom();
            count++;
        }
        Set<String> hashSet=new HashSet<>();
        for (String temp:arr
             ) {
            if (!hashSet.add(temp)){
                flag++;
                tempList.add(temp);
            }
        }
        System.out.println("重复的元素有"+flag+"个");
        System.out.println("分别是以下");
        System.out.println(tempList);


    }

    //获得一个char的随机字符
    private static String charRandom(){
        String s="";
        int count=0;
        Random random=new Random();
        for (;;){
            char c= (char)(random.nextInt(90-65)+65);
            if (Character.isLetterOrDigit(c)){
                s += c;
                count++;
                if (count==2){
                    break;
                }
            }
        }
        return s;
    }
}

							


2 个答案

玉子
答案时间:2023-11-01
/** * 在比较字符串章节,有一个同样的练习 * 创建一个长度是100的字符串数组 * 使用长度是2的随机字符填充该字符串数组 * 统计这个字符串数组里重复的字符串有多少种 * 使用HashSet来解决这个问题 */ public static void main(String[] args) { HashSet<String> strsSet=new HashSet(); ArrayList<String> tj = new ArrayList<>(); String[] arrStr=new String[100]; for (int i = 0; i < arrStr.length; i++) { String randomStr = getRandom(2); System.out.print(randomStr+","); arrStr[i]=randomStr; //set的特性 不能重复 if (!strsSet.add(randomStr)){ tj.add(randomStr); } } System.out.println(); System.out.println("数组里重复的字符串有"+tj.size()+"种,见如下"); for (int i = 0; i < tj.size(); i++) { System.out.print(tj.get(i)+","); } } //生成数字和大小写混合的指定长度随机字符串 public static String getRandom(int n){ String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; StringBuilder sb = new StringBuilder(); for (int i = 0; i < n; i++) { int index = (int) (Math.random() * chars.length()); sb.append(chars.charAt(index)); } return sb.toString(); }

xiaoba_java
答案时间:2023-10-08
我觉得这个代码效率比答案的更高



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2022-10-21 HastSet答案
2022-09-13 hashset答案
2022-05-31 答案


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 50 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 JAVA 中级-集合框架-HashSet 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图