Skip to content

Commit

Permalink
Add sets concept (#2769)
Browse files Browse the repository at this point in the history
  • Loading branch information
sanderploegsma authored Apr 4, 2024
1 parent 098daf2 commit ebfb3ed
Show file tree
Hide file tree
Showing 16 changed files with 711 additions and 0 deletions.
5 changes: 5 additions & 0 deletions concepts/sets/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"blurb": "Sets are unordered collections that do not allow duplicates.",
"authors": ["sanderploegsma"],
"contributors": []
}
52 changes: 52 additions & 0 deletions concepts/sets/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# About

A [`Set`][set-docs] is an unordered collection that (unlike `List`) is guaranteed to not contain any duplicate values.

The generic type parameter of the `Set` interface denotes the type of the elements contained in the `Set`:

```java
Set<Integer> ints = Set.of(1, 2, 3);
Set<String> strings = Set.of("alpha", "beta", "gamma");
Set<Object> mixed = Set.of(1, false, "foo");
```

Note that the `Set.of()` method creates an [_unmodifiable_][unmodifiable-set-docs] `Set` instance.
Trying to call methods like `add` and `remove` on this instance will result in an exception at run-time.

To create a modifiable `Set`, you need to instantiate a class that implements the `Set` interface.
The most-used built-in class that implements this interface is the [`HashSet`][hashset-docs] class.

```java
Set<Integer> ints = new HashSet<>();
```

The `Set` interface extends from the [`Collection`][collection-docs] and [`Iterable`][iterable-docs] interfaces, and therefore shares a lot of methods with other types of collections.
A notable difference to the `Collection` interface, however, is that methods like `add` and `remove` return a `boolean` (instead of `void`) which indicates whether the item was contained in the set when that method was called:

```java
Set<Integer> set = new HashSet<>();
set.add(1);
// => true
set.add(2);
// => true
set.add(1);
// => false
set.size();
// => 2
set.contains(1);
// => true
set.contains(3);
// => false
set.remove(3);
// => false
set.remove(2);
// => true
set.size();
// => 1
```

[collection-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Collection.html
[hashset-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashSet.html
[iterable-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Iterable.html
[set-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html
[unmodifiable-set-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html#unmodifiable
52 changes: 52 additions & 0 deletions concepts/sets/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Introduction

A [`Set`][set-docs] is an unordered collection that (unlike `List`) is guaranteed to not contain any duplicate values.

The generic type parameter of the `Set` interface denotes the type of the elements contained in the `Set`:

```java
Set<Integer> ints = Set.of(1, 2, 3);
Set<String> strings = Set.of("alpha", "beta", "gamma");
Set<Object> mixed = Set.of(1, false, "foo");
```

Note that the `Set.of()` method creates an [_unmodifiable_][unmodifiable-set-docs] `Set` instance.
Trying to call methods like `add` and `remove` on this instance will result in an exception at run-time.

To create a modifiable `Set`, you need to instantiate a class that implements the `Set` interface.
The most-used built-in class that implements this interface is the [`HashSet`][hashset-docs] class.

```java
Set<Integer> ints = new HashSet<>();
```

The `Set` interface extends from the [`Collection`][collection-docs] and [`Iterable`][iterable-docs] interfaces, and therefore shares a lot of methods with other types of collections.
A notable difference to the `Collection` interface, however, is that methods like `add` and `remove` return a `boolean` (instead of `void`) which indicates whether the item was contained in the set when that method was called:

```java
Set<Integer> set = new HashSet<>();
set.add(1);
// => true
set.add(2);
// => true
set.add(1);
// => false
set.size();
// => 2
set.contains(1);
// => true
set.contains(3);
// => false
set.remove(3);
// => false
set.remove(2);
// => true
set.size();
// => 1
```

[collection-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Collection.html
[hashset-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashSet.html
[iterable-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Iterable.html
[set-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html
[unmodifiable-set-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html#unmodifiable
10 changes: 10 additions & 0 deletions concepts/sets/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"url": "https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html",
"description": "java.util.Set API documentation"
},
{
"url": "https://www.baeldung.com/java-set-operations",
"description": "Implementing set operations in Java"
}
]
18 changes: 18 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,19 @@
"prerequisites": [
"numbers"
]
},
{
"slug": "gotta-snatch-em-all",
"name": "gotta-snatch-em-all",
"uuid": "a7938215-4597-4c51-8ceb-6514d5654485",
"concepts": [
"sets"
],
"prerequisites": [
"lists",
"generic-types"
],
"status": "beta"
}
],
"practice": [
Expand Down Expand Up @@ -1890,6 +1903,11 @@
"slug": "randomness",
"name": "Randomness"
},
{
"uuid": "775572da-46f5-4d8a-b154-f35ae344ea40",
"slug": "sets",
"name": "Sets"
},
{
"uuid": "8a468b14-724a-4036-8edb-d19a02809840",
"slug": "strings",
Expand Down
32 changes: 32 additions & 0 deletions exercises/concept/gotta-snatch-em-all/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Hints

## General

- The [`Set` API documentation][set-docs] contains a list of methods available on the `Set` interface.

## 1. Start a collection

- The [`HashSet` class][hashset-docs] has a constructor that takes a `Collection`.

## 2. Grow the collection

- Check out the signature of the [`add` method][set-add-docs] defined on the `Set` interface.

## 3. Start trading

- You can create a copy of a `Set` by wrapping it in a `new HashSet<>()`.
- The [`Set` interface][set-docs] has a method that removes all items contained in another `Collection`.

## 4. Identify common cards

- You can create a copy of a `Set` by wrapping it in a `new HashSet<>()`.
- The [`Set` interface][set-docs] has a method that retains all items contained in another `Collection`.

## 5. All of the cards

- You can create a copy of a `Set` by wrapping it in a `new HashSet<>()`.
- The [`Set` interface][set-docs] has a method that adds all items contained in another `Collection`.

[hashset-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashSet.html
[set-add-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html#add(E)
[set-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html
80 changes: 80 additions & 0 deletions exercises/concept/gotta-snatch-em-all/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Instructions

Your nostalgia for Blorkemon™️ cards is showing no sign of slowing down, you even started collecting them again, and you
are getting your friends to join you.

In this exercise, you will use the `Set` interface to help you manage your collection, since duplicate cards are not
important when your goal is to get all existing cards.

## 1. Start a collection

You just found your old stash of Blorkemon™️ cards! so it's time to start a new collection!
The stash contains a bunch of duplicate cards, so it's time to start a new collection by removing the duplicates.

You really want your friends to join your Blorkemon™️ madness, and the best way is to kickstart their collection by
giving them one card.

Implement the `newCollection` method, which transforms a list of cards into a `Set` representing your new collection.

```java
GottaSnatchEmAll.newCollection(List.of("Newthree", "Newthree", "Newthree"));
// => {"Newthree"}
```

## 2. Grow the collection

Once you have a collection, it takes a life of its own and must grow.

Implement the `addCard` method, which takes a new card and your current set of collected cards.
The method should add the new card to the collection if it isn't already present, and should return a `boolean`
indicating whether the collection was updated.

```java
Set<String> collection = GottaSnatchEmAll.newCollection("Newthree");
GottaSnatchEmAll.addCard("Scientuna",collection);
// => true

collection.contains("Scientuna");
// => true
```

## 3. Start trading

You really want your friends to join your Blorkemon™️ madness, so it's time to start trading!

Not every trade is worth doing, or can be done at all.
You cannot trade a card you don't have, and you shouldn't trade a card for one that you already have.

Implement the `canTrade` method, that takes your current collection and the collection of one of your friends.
It should return a `boolean` indicating whether a trade is possible, following the rules above.

```java
Set<String> myCollection = Set.of("Newthree");
Set<String> theirCollection = Set.of("Scientuna");
GottaSnatchEmAll.canTrade(myCollection, theirCollection);
// => true
```

## 4. Identify common cards

You and your Blorkemon™️ enthusiast friends gather and wonder which cards are the most common.

Implement the `commonCards` method, which takes a list of collections and returns a collection of cards that all collections
have.

```java
GottaSnatchEmAll.commonCards(List.of(Set.of("Scientuna"), Set.of("Newthree","Scientuna")));
// => {"Scientuna"}
```

## 5. All of the cards

Do you and your friends collectively own all of the Blorkemon™️ cards?

Implement the `allCards` method, which takes a list of collections and returns a collection of all different cards in
all the collections combined.

```java
GottaSnatchEmAll.allCards(List.of(Set.of("Scientuna"), Set.of("Newthree","Scientuna")));
// => {"Newthree", "Scientuna"}
```
54 changes: 54 additions & 0 deletions exercises/concept/gotta-snatch-em-all/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Introduction

## Sets

A [`Set`][set-docs] is an unordered collection that (unlike `List`) is guaranteed to not contain any duplicate values.

The generic type parameter of the `Set` interface denotes the type of the elements contained in the `Set`:

```java
Set<Integer> ints = Set.of(1, 2, 3);
Set<String> strings = Set.of("alpha", "beta", "gamma");
Set<Object> mixed = Set.of(1, false, "foo");
```

Note that the `Set.of()` method creates an [_unmodifiable_][unmodifiable-set-docs] `Set` instance.
Trying to call methods like `add` and `remove` on this instance will result in an exception at run-time.

To create a modifiable `Set`, you need to instantiate a class that implements the `Set` interface.
The most-used built-in class that implements this interface is the [`HashSet`][hashset-docs] class.

```java
Set<Integer> ints = new HashSet<>();
```

The `Set` interface extends from the [`Collection`][collection-docs] and [`Iterable`][iterable-docs] interfaces, and therefore shares a lot of methods with other types of collections.
A notable difference to the `Collection` interface, however, is that methods like `add` and `remove` return a `boolean` (instead of `void`) which indicates whether the item was contained in the set when that method was called:

```java
Set<Integer> set = new HashSet<>();
set.add(1);
// => true
set.add(2);
// => true
set.add(1);
// => false
set.size();
// => 2
set.contains(1);
// => true
set.contains(3);
// => false
set.remove(3);
// => false
set.remove(2);
// => true
set.size();
// => 1
```

[collection-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Collection.html
[hashset-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/HashSet.html
[iterable-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Iterable.html
[set-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html
[unmodifiable-set-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html#unmodifiable
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Introduction

%{concept:sets}
27 changes: 27 additions & 0 deletions exercises/concept/gotta-snatch-em-all/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"authors": [
"sanderploegsma"
],
"contributors": [
"kahgoh"
],
"files": {
"solution": [
"src/main/java/GottaSnatchEmAll.java"
],
"test": [
"src/test/java/GottaSnatchEmAllTest.java"
],
"exemplar": [
".meta/src/reference/java/GottaSnatchEmAll.java"
],
"invalidator": [
"build.gradle"
]
},
"forked_from": [
"elm/gotta-snatch-em-all"
],
"icon": "character-study",
"blurb": "Learn to use sets by playing a vintage trading card game"
}
Loading

0 comments on commit ebfb3ed

Please sign in to comment.