In another post of Java Generics you have seen how to create a generic collection using List in this example you will learn how to make a generic Set. Making a Set generic means that we want it to only hold objects of the defined type. We can declare and instantiate a generic Set like the following code.
Set<String> colors = new HashSet<>();
We use the angle brackets to define the type. We need also to define the type in the instantiation part, but using the diamond operator remove the duplicate and Java will infer the type itself. This declaration and instantiation will give you a Set object that holds a reference to String objects. If you tried to ask it to hold other type of object such as Date or Integer you will get a compiled time error.
Set<String> colors = new HashSet<>();
colors.add("Red");
colors.add("Green");
colors.add("Blue");
//colors.add(new Date()); // Compile time error!
The code for adding items to a set is look the same with the old way we code. But again, one thing you will get here for free is that the compiler will check to see if you add the correct type to the Set. If we remove the remark on the last line from the snippet above we will get a compiled time error. Because we are trying to store a Date into a Set of type String.
Now, let see how we can iterate the contents of the Set. First we’ll do it using the Iterator. And here is the code snippet.
Iterator iterator = colors.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
When using a generic Set it will know that the iterator.next() will return a type of String so that you don’t have use the cast operator. Which of course will make you code looks cleaner and more readable. We can also using the for-each loop when iterating the Set as can be seen in the following example.
for (String color : colors) {
System.out.println(color);
}
The Album bean have a songs property that have a type of java.util.List. The <set> element does not have to be used with java.util.Set. It can be used to wire a java.util.List collection. It just means it cannot contain duplicate values in it, so the collection will only contain a unique values.
The <set> configuration can bee seen in the album bean configuration. We set the songs property. Within this property element we use the <set> element. And then using the <ref> element we add some bean into the collection.
Create the following code to run it:
package org.kodejava.spring.core;
public class Song {
private String title;
private String writer;
public Song() {
}
public void setTitle(String title) {
this.title = title;
}
public void setWriter(String writer) {
this.writer = writer;
}
@Override
public String toString() {
return "Song{" +
"title='" + title + '\'' +
", writer='" + writer + '\'' +
'}';
}
}
package org.kodejava.spring.core;
public class Publisher {
private String name;
public Publisher() {
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Publisher{" +
"name=" + name +
'}';
}
}
package org.kodejava.spring.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class Album {
private String title;
private int year;
private List<Song> songs = new ArrayList<>();
private Map<String, Publisher> publisher = new HashMap<>();
private Properties props = new Properties();
public Album() {
}
public void setTitle(String title) {
this.title = title;
}
public void setYear(int year) {
this.year = year;
}
public void setSongs(List<Song> songs) {
this.songs = songs;
}
public void setPublisher(Map<String, Publisher> publisher) {
this.publisher = publisher;
}
public void setProps(Properties props) {
this.props = props;
}
@Override
public String toString() {
return "Album{" +
"title='" + title + '\'' +
", year=" + year +
", songs=" + songs +
", publisher=" + publisher +
", props=" + props +
'}';
}
}
package org.kodejava.spring.core;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoSet {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("collection-set.xml");
Album album = (Album) context.getBean("album");
System.out.println("Album = " + album);
context.close();
}
}
You’ll see the following output in the screen. As you can see, although we set three beans into the songs property, the Album bean only contain a one song. This is because we use the <set> element to wire the collection. It does not allow duplicate values.
Album = Album{title='Please Please Me', year=1963, songs=[Song{title='I Saw Her Standing There', writer='Beatles'}], publisher={}, props={}}
package org.kodejava.util;
import java.util.*;
public class SetToArray {
public static void main(String[] args) {
// Create a java.util.Set object and add some integers into the Set.
Set<Integer> numberSet = new HashSet<>();
numberSet.add(1);
numberSet.add(2);
numberSet.add(3);
numberSet.add(5);
numberSet.add(8);
// Converting a java.util.Set into an array can be done by creating a
// java.util.List object from the Set and then convert it into an array
// by calling the toArray() method on the list object.
List<Integer> numberList = new ArrayList<>(numberSet);
Integer[] numbers = numberList.toArray(new Integer[0]);
// Display the content of numbers array.
for (int i = 0; i < numbers.length; i++) {
Integer number = numbers[i];
System.out.print(number + (i < numbers.length - 1 ? ", " : "\n"));
}
// Display the content of numbers array using the for-each loop.
for (Integer number : numbers) {
System.out.print(number + ", ");
}
}
}
The code below gives you an example of converting a java.util.Set into a java.util.List. It has simply done by creating a new instance of List and pass the Set as the argument of the constructor.
package org.kodejava.util;
import java.util.*;
public class SetToList {
public static void main(String[] args) {
// Create a Set and add some objects into the Set.
Set<Object> set = new HashSet<>();
set.add("A");
set.add(10L);
set.add(new Date());
// Convert the Set to a List can be done by passing the Set instance into
// the constructor of a List implementation class such as ArrayList.
List<Object> list = new ArrayList<>(set);
for (Object o : list) {
System.out.println("Object = " + o);
}
}
}
The output of the code snippet are:
Object = A
Object = 10
Object = Mon Oct 04 20:20:26 CST 2021
The trick to sort a java.util.Set is to use the implementation of a java.util.SortedSet such as the java.util.TreeSet class. The example below shows you the result of using the java.util.TreeSet class, in which the items in it will be sorted based on the element’s natural order.
package org.kodejava.util;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
// The TreeSet class is an implementation of a SortedSet, this means
// that when you are using the TreeSet to store you data collections
// you'll get the items ordered base on its elements natural order.
Set<String> set = new TreeSet<>();
// In the example below we add some letters to the TreeSet, this mean
// that the alphabets will be ordered based on the alphabet order
// which is from A to Z.
set.add("Z");
set.add("A");
set.add("F");
set.add("B");
set.add("H");
set.add("X");
set.add("N");
for (String item : set) {
System.out.print(item + " ");
}
}
}
This example demonstrates you how to remove duplicate elements from an array using the help of java.util.HashSet class.
package org.kodejava.util;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ArrayRemoveDuplicate {
public static void main(String[] args) {
// A string array with duplicate values.
String[] data = {"A", "C", "B", "D", "A", "B", "E", "D", "B", "C"};
System.out.println("Original array : " + Arrays.toString(data));
// Convert a string array into java.util.List because we need a list
// object to create the java.util.Set object.
List<String> list = Arrays.asList(data);
// A set is a collection object that cannot have a duplicate values,
// by converting the array to a set the duplicate value will be removed.
Set<String> set = new HashSet<>(list);
// Convert the java.util.Set back to array using the toArray() method of
// the set object copy the value in the set to the defined array.
String[] result = set.toArray(new String[0]);
System.out.println("Array with no duplicate: " + Arrays.toString(result));
}
}
The result of the code snippet above:
Original array : [A, C, B, D, A, B, E, D, B, C]
Array with no duplicate: [A, B, C, D, E]
package org.kodejava.util;
import java.util.*;
public class ArrayToSetExample {
public static void main(String[] args) {
Integer[] numbers = {7, 7, 8, 9, 10, 8, 8, 9, 6, 5, 4};
// To convert an array into a java.util.Set firstly we need to convert the
// array into a java.util.List using the Arrays.asList() method. With the
// List object created we can instantiate a new java.util.HashSet and pass
// the list as the constructor parameter.
List<Integer> numberList = Arrays.asList(numbers);
Set<Integer> numberSet = new HashSet<>(numberList);
// Or we can simply combine the line above into single line.
Set<Integer> anotherNumberSet = new HashSet<>(Arrays.asList(numbers));
// Display what we get in the set using iterator.
for (Iterator<Integer> iterator = numberSet.iterator(); iterator.hasNext(); ) {
Integer number = iterator.next();
System.out.print(number + ", ");
}
// Display what we get in the set using for-each.
for (Integer number : anotherNumberSet) {
System.out.print(number + ", ");
}
}
}