I want to do a get request and want to get all the jobs who have the "teacher" in it. In this case the map value 2 and 3.
How do I get there if I execute the code below then I only get the value from the Map 2. The best way is over a List? But how do I do it?
I have this method.
@GET
@Path("jobs")
public Job getJobsId(@QueryParam("id") int id, @QueryParam("description") String description) {
for (final Map.Entry<Integer, Job> entry : jobs.entrySet()) {
if (entry.getValue().getDescription().toLowerCase().contains(description.toLowerCase())) {
System.out.println("I DID IT");
System.out.println(entry.getKey());
return berufe.get(entry.getKey());
}
}
return berufe.get(id);
}
and this Map:
jobs.put(1, new jobs(1, 1337, "student"));
jobs.put(2, new jobs(2, 420, "teacher"));
jobs.put(3, new jobs(3, 69, "schoolteacher"));
---------------------------------EDIT----------------------------------
If I do this:
@GET
@Path("jobs")
public Collection<Job> getJobsId(@QueryParam("id") int id, @QueryParam("description") String description) {
final Set<Beruf> result = new HashSet<>();
for (final Map.Entry<Integer, Job> entry : jobs.entrySet()) {
if (entry.getValue().getDescription().toLowerCase().contains(description.toLowerCase()) == true) {
result.add(jobs.get(entry.getKey()));
} else {
return jobs.values();
}
}
return result;
}
I get with a discription all Map values back and without I get an Error.
What do I do wrong here?
CodePudding user response:
Your method getJobsId()
returns on the first item it finds (inside the if
statement), that's why you only get one result.
The usual pattern to collect a number of results would be to instantiate a suitable Collection
before the for
loop, and add each item that is found to this collection. Then, after the for
loop, return the collection. I don't understand your code completely, but it would be something similar to the below (I'm sure it won't work if you just copy-paste, so read and understand what is going on ;-) ):
Set<Beruf> result = new HashSet<>();
for (final Map.Entry<Integer, Job> entry : jobs.entrySet()) {
if (entry.getValue().getDescription().toLowerCase().contains(description.toLowerCase())) {
result.add(berufe.get(entry.getKey()));
}
}
return result;
Since Java 8, it has been much more concise (readable) to use the Streams
interface and call .filter
(and maybe .map
) on it, then .collect
the stream to a suitable collection and return that. Something similar to:
return jobs.entrySet().stream()
.filter(entry -> (entry.getValue().getDescription().toLowerCase().contains(description.toLowerCase())))
.map(entry -> berufe.get(entry.getKey()))
.collect(Collectors.toSet());
CodePudding user response:
A function can return only one element. If there more than one hit, you have to return an object that can take on multiple elements. As you already mentioned a list, as an representant of a collection, can do this job. For your use case is a map a better option:
@GET
@Path("jobs")
public Job getJobsId(@QueryParam("id") int id, @QueryParam("description") String description)
{
//Declare an object that can take on multiple elements
var Map<Job> jobList = new HashMap<>();
for (final Map.Entry<Integer, Job> entry : jobs.entrySet())
{
if (entry.getValue().getDescription().toLowerCase().contains(description.toLowerCase()))
{
System.out.println("I DID IT");
System.out.println(entry.getKey());
jobList.put(entry.getKey(), job.get(entry.getKey()));
}
}
return jobList.get(id);
}
CodePudding user response:
First of all, you should do is design the API correctly, for example:
@GET
@Path("jobs")
public List<Integer> searchJobsIdByDescription(@QueryParam("description") String description) {
...
}
Important: you must give a suitable name to the method (f.e: searchJobsIdByDescription
), your method should only do one thing, so you declare only the parameters needed to do that thing (f.e: (@QueryParam("description") String description)
) and return the expected type (List<Integer>
).
Pay attention to the annotation @Path("jobs")
, you have to avoid matching the previous ones
Next, you should carefully read @frIV's answer