Problem
- The front-end team wants an API endpoint that allows them to send a List of domain names and API returns to which of them are available domains to register.
- As a backend engineer, our task is to write a logic to take a list of domains as input and return the ones that are already registered and not available.
- We have also been given a List of all the domains that are registered so far.
Example,
Input Domain List
- List of domains that we need to assess if they have already registered or not.
List<String> input = List.of(
"abc.com",
"dvt9gi7qs2.net",
"zd9iekl5yq.com",
"sknzyhxc72.io",
"qejcd86aq5.net"
);
List of Registered Domains
- List of domains that are already registered.
[j7fc13jenn.io, dvt9gi7qs2.net, 1su8jnwoz4.net, a5newko5s7.io, qejcd86aq5.net]
Output
- We have two domains that are not registered.
[dvt9gi7qs2.net, qejcd86aq5.net]
Before jumping to the solution consider giving an attempt.
Solution
- We are discussing 4 options to solve this problem. If you have any other solution please add that to the comments, we would love to see them!
#1
- In this solution, we are iterating over the input domain using streams API. Then for each domain name, we search for it in a registered domain list and whichever domain exists in it we return it to the collector.
List<String> output = input.stream()
.map(d -> domains.stream().filter(d1 -> d1.equals(d)).findAny())
.filter(Optional::isPresent)
.map(Optional::get)
.toList();
#2
- We can shorten the below code using the contains() method provided by the list.
.map(d -> domains.stream().filter(d1 -> d1.equals(d)).findAny())
.filter(domains::contains)
- With this modification, our solution becomes shorter.
List<String> output = input.stream()
.filter(domains::contains)
.toList();
#3
- We can reduce our search by creating a hashmap of domain extensions ( such as .org ) with a registered domain name.
Map<String, List<String>> groupedByDomains = domains.stream()
.collect(Collectors.groupingBy(d ->
d.substring(d.lastIndexOf("."), d.length()))
);
System.out.println(groupedByDomains);
- groupedByDomains would look like the below
{.io=[j7fc13jenn.io, a5newko5s7.io, go6f8qzvqz.io, hwcwdhkz4a.io, tfhk6rqg92.io ... ], .com=[4vejwyc9zc.com, bwv2ormwb1.com, ov6z3vfxee.com ... ] }
- Once we have the reduced target search we can improve the search performance.
- We need to do some processing before we can start the search in the target area. In the below logic, we are extracting the domain extension .com/.org and using that as a key for our hashmap to find the target search.
List<String> output = input.stream()
.filter(d -> {
String tld = d.substring(d.lastIndexOf("."), d.length());
return groupedByDomains.containsKey(tld) && groupedByDomains.get(tld).contains(d);
})
.toList();
#4
- We can also convert registered domains into HashSet. By doing so it will allow us to search any domain in constant time.
Set<String> domainsSet = new HashSet<String>(domains);
- Once we have set all we have to stream over the input domain and search it in HashSet of the registered domain.
List<String> output = input.stream()
.filter(domainsSet::contains)
.toList();
Code
- Find all the code for this & others exercises on GitHub
Conclusion
- In this problem, we provided 4 solutions using different approaches. We used streams API to iterate over input data and perform processing. Our solution contains some optimization for search as well.
Over to you! Write down your solution in the comment section for others to get back to it
Before You Leave
- Upgrade your Java skills with Grokking the Java Interview.
- If you want to upskill your Java skills, you should definitely check out
[NEW] Master Spring Boot 3 & Spring Framework 6 with Java
[ 38 hrs content, 4.7/5 stars, 6+ students already enrolled]
Other Problems List