如何使用java.Set

问题描述 投票:0回答:6

我试图让它工作很长一段时间,但似乎无法得到它。我有一个用 Block 建造的物体塔。我已经使用数组让它工作了,但我想学习 Set 的。我想获得与此类似的功能:

public class Tower {


public Tower(){
}

public Tower add(Block k1){

    //(...)
    //if block already in tower, return "Block already in tower"
}

public Tower delete(Block k1){

    //(...)
    //if block already dleted, show "No such block in tower"
}

}

有人给了我一些代码,但我在尝试使用它时经常遇到错误:

Set<Block> tower = new HashSet<Block>();

boolean added = tower.add( k1 );
if( added ) {
System.out.println("Added 1 block.");
} else {
System.out.println("Tower already contains this block.");
}

如何实施?

java collections interface set
6个回答
56
投票

首先需要学习的是

java.util.Set
API

这是一个如何使用其方法的小示例:

    Set<Integer> numbers = new TreeSet<Integer>();

    numbers.add(2);
    numbers.add(5);

    System.out.println(numbers); // "[2, 5]"
    System.out.println(numbers.contains(7)); // "false"

    System.out.println(numbers.add(5)); // "false"
    System.out.println(numbers.size()); // "2"

    int sum = 0;
    for (int n : numbers) {
        sum += n;
    }
    System.out.println("Sum = " + sum); // "Sum = 7"

    numbers.addAll(Arrays.asList(1,2,3,4,5));
    System.out.println(numbers); // "[1, 2, 3, 4, 5]"

    numbers.removeAll(Arrays.asList(4,5,6,7));
    System.out.println(numbers); // "[1, 2, 3]"

    numbers.retainAll(Arrays.asList(2,3,4,5));
    System.out.println(numbers); // "[2, 3]"

一旦熟悉了 API,您就可以使用它来包含更多有趣的对象。如果您还没有熟悉

equals
hashCode
合约,那么现在是开始的好时机。

简而言之:

  • @Override
    两者或都没有;永远不会只有一个。(非常重要,因为它必须满足属性:
    a.equals(b) == true --> a.hashCode() == b.hashCode()
    • 请小心书写
      boolean equals(Thing other)
      ;这不是正确的
      @Override
  • 对于非空引用
    x, y, z
    equals
    必须是:
    • 反身:
      x.equals(x)
    • 对称:
      x.equals(y)
      当且仅当
      y.equals(x)
    • 传递:如果
      x.equals(y) && y.equals(z)
      ,则
      x.equals(z)
    • 一致:
      x.equals(y)
      不得改变,除非对象发生了突变
    • x.equals(null) == false
  • hashCode
    的总合约为:
    • 一致:返回相同的数字,除非发生突变
    • equals
      一致:如果
      x.equals(y)
      ,则
      x.hashCode() == y.hashCode()
      • 严格来说,对象不等式并不需要哈希码不等式
      • 但是哈希码不等式必然需要对象不等式
  • 算作突变的内容应在
    equals
    hashCode
    之间保持一致。

接下来,您可能想要对对象进行排序。您可以通过使类型实现

Comparable
或提供单独的
Comparator
来实现此目的。

拥有其中任何一个都可以轻松对对象进行排序(

Arrays.sort
Collections.sort(List)
)。它还允许您使用
SortedSet
,例如
TreeSet


有关 stackoverflow 的更多阅读:


2
投票

您是否在 Block 类中重写了 equals 和 hashCode

编辑:

我以为你的意思是它在运行时不起作用......你是指这个还是在编译时?如果编译时错误信息是什么?如果它在运行时崩溃,堆栈跟踪是什么?如果它编译并运行但无法正常工作,那么 equals 和 hashCode 可能是问题。


1
投票

仅凭所提供的信息很难回答这个问题。您使用 HashSet 的方式看起来没有什么特别错误的。

好吧,我大胆猜测这不是编译问题,当你说“出现错误”时,你的意思是“没有得到[你]想要的行为。”

我也会大胆地建议,也许你的 Block 等于 hashCode 方法没有被正确覆盖。


0
投票

由于它是一个 HashSet,因此您需要重写 hashCodeequals 方法。 http://preciselyconcise.com/java/collections/d_set.php 有一个示例解释如何实现 hashCode 和 equals 方法


0
投票

如果您必须采用由空格分隔的一对字符串并计算每个级别中存在的唯一字符串,那么以下逻辑将对您有所帮助。

import java.io.*;
import java.util.*;

public class Solution {

 public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        Set<String> st=new HashSet<>();
        int t = s.nextInt();
        String [] pair_left = new String[t];
        String [] pair_right = new String[t];
        
        for (int i = 0; i < t; i++) {
            pair_left[i] = s.next();
            pair_right[i] = s.next();

        }
        for(int i=0;i<t;i++)
        {
            st.add(pair_left[i]+" "+pair_right[i]);
            System.out.println(st.size());
        }

//Write your code here

   }
}

输出: 3 甲乙 甲乙 光盘 1 1 2


0
投票

看起来你需要按照上面的建议实现 hashcode 和 equals 方法。另外 Set 只会存储唯一元素。如果你尝试存储重复的元素,它不会执行任何操作,但你可以通过获取其状态来检查这些重复项。这将是 true如果 add 方法能够添加元素,并且如果发现重复元素,则返回 false。此外,您还可以参考下面一些有关 Set 的基本文章来获取更多详细信息。

https://www.geeksforgeeks.org/set-in-java/ https://theuniquecontent.com/set-in-java/

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.