Jersey, #QueryParam List<String> - jersey

I want to take a list as a parameter, but the value of the list does not correspond to java version list. For example #QueryParam("orderBy") List orderBy)
This list has the value of [age, name] as an element.
Is it possible to have the value separately. Like 1st element age and 2nd element name.
`
#GET
#Path("/range")
#Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public Response searchForActivitiesWithRange(#QueryParam(value = "description")List<String> descriptions,
#QueryParam(value = "durationFrom") int durationFrom,
#QueryParam(value = "durationTo") int durationTo) {
List<Activity> activities = activityRepository.findByDescriptionandDuration(descriptions,durationFrom,durationTo);
if (activities == null || activities.size() == 0) {
return Response.status(Status.NOT_FOUND).build();
}
return Response.ok().entity(new GenericEntity<List<Activity>>(activities){}).build();
}`

Not automatically. Every query param is read by jersey as a String and, after, it tries to convert in the data type of the parameter you specified.
You have to split the param String or,client side, send multiple param with the same name and read them like a MultivaluedMap, in which the key is the param name and the value a list with all values.

Use objects. You can create an ActivitiesRequest class and then define your variables in the class. You can also do that for your response.

Related

Getting a column by string name

I'm trying to update a record given the customer Id, the row Id, and a dynamic column name.
Thus far I have the following, with the trouble spot marked by ***:
public void UpdateRecord(int Id, string rval, string column, string value)
{
var rId = GetRvalId(rval);
var entry = _context.Customers
.Where(x => x.Id == Id && x.RVals.Id == rId && x.***column?*** == column).First();
entry = value;
}
I haven't been able to find a good example of how to do this.
Addition after comments at the end
The reason you couldn't find examples is because it is not a good design.
Your method is very error prone, difficult to test and horrible to maintain. What if someone types the incorrect column name? What if you try to assign a string to the customer's birthday? And even if you would implement some string checking for column names and proposed values, then your program wouldn't work anymore after someone changes the names or the types of the columns.
So let's redesign!
Apparently you have a Customer with an Id and a property Rvals. This property Rvals also has a property Id.
You also have a function GetRValId that can convert a string rval to an int rvalId.
What you want, is given an Id and a string rval, you want to update one of the columns of the first Customer with this Idand rValId.
Side questions: Can there be more than one Customer with Id? In that case: are you sure Id is an ID? What do you want if there are more matching Customers? Update all customers or update only the first one? Which customer do you define as the first customer?
Leaving the side questions aside. We want a function signature that reports errors at compile time if you use non-existing customer properties, or if you try to assign a string to a Birthday. Something like this perhaps?
Update the name of the customer:
int customerId = ...
string rval = ...
string proposedName = "John Doe";
UpdateCustomerRecord(id, rval, customer => customer.Name = proposedName);
Update the Birthday of the customer:
DateTime proposedBirthday = ...
UpdateCustomerRecord(id, rval, customer => customer.Birthday = proposedBirthday)
This way you can't use any column that does not exist, and you can't assign a string to a DateTime.
You want to change two values in one call? Go ahead:
UpdateCustomerRecord(id, rval, customer =>
{
customer.Name = ...;
customer.Birthday = ...;
});
Convinced? Let's write the function:
public void UpdateCustomerRecord(int customerId, string rval, Action<Customer> action)
{
// the beginning is as in your function:
var rId = GetRvalId(rval);
// get the customer that you want to update:
using (var _Context = ...)
{
// get the customer you want to update:
var customerToUpdate = _Context.Customers
.Where(customer => customer.Id == Id
&& customer.RVals.Id == rId)
.FirstOrDefault();
// TODO: exception if there is no customerToUpdate
// perform the action and save the changes
action(customerToUpdate);
_context.SaveChanges();
}
Simple comme bonjour!
Addition after comments
So what does this function do? As long as you don't call it, it does nothing. But when you call it, it fetches a customer, performs the Action on the Customer you provided in the call, and finally calls SaveChanges.
It doesn't do this with every Customer, no it does this only with the Customer with Id equal to the provided Id and customer.RVals.Id == ... (are you still certain there is more than one customer with this Id? If there is only one, why check for RVals.Id?)
So the caller not only has to provide the Id, and the RVal, which define the Customer to update, but he also has to define what must be done with this customer.
This definition takes the form of:
customer =>
{
customer.Name = X;
customer.BirthDay = Y;
}
Well if you want, you can use other identifiers than customer, but it means the same:
x => {x.Name = X; x.BirthDay = Y;}
Because you put it on the place of the Action parameter in the call to UpdateCustomerRecord, I know that x is of type Customer.
The Acton statement means: given a customer that must be updated, what must we do with the customer? You can read it as if it was a Function:
void Action(Customer customer)
{
customer.Name = ...
customer.BirthDay = ...
}
In the end it will do something like:
Customer customerToUpdate = ...
customerToUpdate.Name = X;
customerToUpdate.BirthDay = Y;
SaveChanges();
So in the third parameter, called Action you can type anything you want, even call functions that have nothing to do with Customers (probably not wise). You have an input parameter of which you are certain that it is a Customer.
See my earlier examples of calling UpdateCustomerRecord, one final example:
UpdateCustomerRecord( GetCustomerId(), GetCustomerRVal,
// 3rd parameter: the actions to perform once we got the customerToUpdate:
customer =>
{
DateTime minDate = GetEarliestBirthDay();
if (customer.BirthDay < minDate)
{ // this Customer is old
customer.DoThingsThatOldPeopleDo();
}
else
{ // this Customer is young
customer.DoThingsThatYoungPeopleDo();
}
}
}
So the Action parameter is just a simpler way to say: "once you've got the Customer that must be updated, please perform this function with the Customer
So if you only want to update a given property of the customer write something like:
UpdateCustomerRecord(... , customer =>
{
Customer.PropertyThatMustBeUpdated = NewValueOfProperty;
}
Of course this only works if you know which property must be updated. But since you wrote "I am trying to update a specific cell." I assume you know which property the cells in this column represent.
It is not possible to pass the column name as the string value in LINQ. Alternate way to do it, if you have the limited number of the column name which can be passed then it can be achieved as below:
public void UpdateRecord(int Id, string rval, string column, string value)
{
var rId = GetRvalId(rval);
var entry = _context.Customers
.Where(x => x.Id == Id &&
x.RVals.Id == rId &&
(x.column1 == value || column == column1) &&
(x.column2 == value || column == column2) &&
(x.column3 == value || column == column3) &&
(x.column4 == value || column == column4) &&
(x.column5 == value || column == column5) &&
)).First();
entry = value;
}
UpdateRecord(5, "rval", "column1", "value");
UpdateRecord(5, "rval", "column2", "value");
UpdateRecord(5, "rval", "column3", "value");
Here, suppose you have the 5 columns that can be passed while calling the funcion UpdateRecord then you can add the 5 clauses in the WHERE as above.
Other way to do it dynamic LINQ
var entry = db.Customers.Where(column + " = " + value).Select(...);

Java8 stream average of object property in collection

I'm new to Java so if this has already been answered somewhere else then I either don't know enough to search for the correct things or I just couldn't understand the answers.
So the question being:
I have a bunch of objects in a list:
try(Stream<String> logs = Files.lines(Paths.get(args))) {
return logs.map(LogLine::parseLine).collect(Collectors.toList());
}
And this is how the properties are added:
LogLine line = new LogLine();
line.setUri(matcher.group("uri"));
line.setrequestDuration(matcher.group("requestDuration"));
....
How do I sort logs so that I end up with list where objects with same "uri" are displayed only once with average requestDuration.
Example:
object1.uri = 'uri1', object1.requestDuration = 20;
object2.uri = 'uri2', object2.requestDuration = 30;
object3.uri = 'uri1', object3.requestDuration = 50;
Result:
object1.uri = 'uri1', 35;
object2.uri = 'uri2', 30;
Thanks in advance!
Take a look at Collectors.groupingBy and Collectors.averagingDouble. In your case, you could use them as follows:
Map<String, Double> result = logLines.stream()
.collect(Collectors.groupingBy(
LogLine::getUri,
TreeMap::new,
Collectors.averagingDouble(LogLine::getRequestDuration)));
The Collectors.groupingBy method does what you want. It is overloaded, so that you can specify the function that returns the key to group elements by, the factory that creates the returned map (I'm using TreeMap here, because you want the entries ordered by key, in this case the URI), and a downstream collector, which collects the elements that match the key returned by the first parameter.
If you want an Integer instead of a Double value for the averages, consider using Collectors.averagingInt.
This assumes LogLine has getUri() and getRequestDuration() methods.

How do I check if a Guid value is inside a LIST of Structures?

How do I check if a Guid value is inside a LIST of Structures?
public struct Info
{
public Guid EntityTypeID;
public String Name;
}
List<Info> InfoList = <function which populates the list of Struct>
...
var values = ctx.EntityValues.Where(v => v.EntityID == e.ID
&& InfoList.Contains(v.EntityTypeItemID)).ToList(); <=== problem here!
//or something like: InfoList[i].EntityTypeID.Contains(v.EntityTypeItemID)).ToList();
Thank you
I suspect you're looking for Any:
... InfoList.Any(x => x.EntityTypeID == v.EntityTypeItemID)
You can't use Contains, because you're looking for something which matches part of the item.
(I'd also strongly discourage using public fields and indeed having mutable structures at all, but that's a different matter.)
Another option would be to create a list of the GUIDs you're interested in:
var guids = InfoList.Select(x => x.EntityTypeID).ToList();
Then you can use:
... guids.Contains(v.EntityTypeItemID)
That may work where the previous code didn't, as it moves the extraction of the type ID out of the main query.

How to remove from an List Object in c#

I have an Action method in my controller which returns a List Object
Public ActionResult GetCats(long Id,string strsortorder,string dltIds)
{
var Result=objrepo.GetCats(Id);//this method returns me List of Result
}
My array looks like this:
var Result=[{CatId:1015,CatName:Abc},{CatId:1016,CatName:Acd},
{CatId:1017,CatName:Adf},{CatId:1018,CatName:CDdf},{CatId:1019,CatName:asdas},
{CatId:1020,CatName:Abc},{CatId:1021,CatName:Abc},{CatId:1022,CatName:Abc},
{CatId:1023,CatName:Abc},{CatId:1024,CatName:Abc}]
What I want to do is:
Using two more parameters in my Action Method "strsortorder" and "dltIds"
that have a list of ids like this:
strsortorder="1021,1015,1016,1019,1022";
dltIds="1017,1018,1020";
From this the "Result" returned from my method , I want to remove the records which are in "dltids" and the remaining array should be sorted in the order which I have in "strsortorder";
In the end the new object should look like this:
var NewResult=[{CatId:1021,CatName:Abc},{CatId:1015,CatName:Abc},
{CatId:1016,CatName:Acd},{CatId:1019,CatName:asdas},{CatId:1022,CatName:Abc},
{CatId:1023,CatName:Abc},{CatId:1024,CatName:Abc}]
Can any one help me in acheiving this in linq or any other way?
I want to avoid any type of loop or froeach here for max extent, I know it can be done by looping but I want to avoid this since the result can sometimes contain large amounts of data.
I realized you can use an ArrayList instead of a Dictionary and it would be faster. I think Dictionary is clear how it works but here is the "better" implementation using array list:
var excludeList = dltIds.Split(",".ToCharArray());
ArrayList sortList = new ArrayList(strsortorder.Split(",".ToCharArray()));
var NewResult =
Result.Where(item => ! excludeList.Contains(item.CatId.ToString()))
.OrderBy(item => {
if (sortList.Contains(item.CatId.ToString()))
return sortList.IndexOf(item.CatId.ToString());
return sortList.Count;
});
Original answer below:
Public ActionResult GetCats(long Id,string strsortorder,string dltIds)
{
var Result=objrepo.GetCats(Id);//this method returns me List of Result
var excludeList = dltIds.Split(",".ToCharArray());
int orderCount = 0; // used in the closure creating the Dictionary below
var sortList = strsortorder.Split(",".ToCharArray())
.ToDictionary(x => x,x => orderCount++);
// filter
var NewResult =
Result.Where(item => ! excludeList.Contains(item.CatId.ToString()))
.OrderBy(item => {
if (sortList.ContainsKey(item.CatId.ToString()))
return sortList[item.CatId.ToString()];
return sortList.Count();
});
}
How this works:
First I create lists out of your comma separated exclude list using split.
This I create a dictionary with the key being the ordering ID and the value being an integer that goes up by one.
For the filtering I look to see if an item is in the exclude array before I continue processing the item.
I then do a sort on matching against the key and the dictionary and returning the value -- this will sort things in the order of the list since I incremented a counter when creating the values. If an item is not in the dictionary I return one more than the maximum value in the dictionary which must be the count of the items. (I could have used the current value of orderCount instead.)
Questions?

How do I use LINQ to obtain a unique list of properties from a list of objects?

I'm trying to use LINQ to return a list of ids given a list of objects where the id is a property. I'd like to be able to do this without looping through each object and pulling out the unique ids that I find.
I have a list of objects of type MyClass and one of the properties of this class is an ID.
public class MyClass
{
public int ID { get; set; }
}
I want to write a LINQ query to return me a list of those Ids.
How do I do that, given an IList<MyClass> such that it returns an IEnumerable<int> of the ids?
I'm sure it must be possible to do it in one or two lines using LINQ rather than looping through each item in the MyClass list and adding the unique values into a list.
IEnumerable<int> ids = list.Select(x=>x.ID).Distinct();
Use the Distinct operator:
var idList = yourList.Select(x=> x.ID).Distinct();
Using straight LINQ, with the Distinct() extension:
var idList = (from x in yourList select x.ID).Distinct();
When taking Distinct, we have to cast into IEnumerable too. If the list is <T> model, it means you need to write code like this:
IEnumerable<T> ids = list.Select(x => x).Distinct();
int[] numbers = {1,2,3,4,5,3,6,4,7,8,9,1,0 };
var nonRepeats = (from n in numbers select n).Distinct();
foreach (var d in nonRepeats)
{
Response.Write(d);
}
Output
1234567890

Resources