Realm java sort with multiple fields - java

I'm sorting like this:
RealmResults<Show> shows = realm.where(Show.class).findAll();
shows.sort("venueTitle", RealmResults.SORT_ORDER_ASCENDING);
How can I sort by multiple properties? Adding another sort line just resets the order of the results entirely.

Looks like they just added this in 0.77. I was using 0.76. Here's the Github issue:
https://github.com/realm/realm-java/issues/648
and here's the API reference:
http://realm.io/docs/java/0.77.0/api/
public void sort(java.lang.String[] fieldNames,
boolean[] sortAscending)

try below code
public RealmResults getSortedList(Class aClass) {
String []fieldNames={"field1","field2"};
Sort sort[]={Sort.ASCENDING,Sort.ASCENDING};
return realm.where(YourClass.class).findAllSorted(fieldNames,sort);
}

Related

Update a list reference inside a method

In Java we can not reassign a reference inside a method.
So the following does not work:
class SomeClass {
List<PaidOrders> paidOrders;
List<PendingOrders> pendingOrders;
List<CancelledOrders> cancelledOrders;
private void process(List<OrderStatus> data, List<Orders> currentOrderlist) {
List<Order> newOrders = fromOrderStatus(data);
currentOrderlist = newOrders;
}
}
But the following does work:
class SomeClass {
private void process(List<OrderStatus> data, List<Orders> currentOrderlist) {
List<Order> newOrders = fromOrderStatus(data);
currentOrderlist.clear();
currentOrderlist.addAll(newOrders); // <- extra linear loop
}
}
The problem is that the second example does an extra linear loop to copy from one list to the other.
Question:
I was wondering, is there some design approach so that I could neatly just replace the references instead? I.e. somehow make the first snippet work with some change in the parameters or something?
Update
After the comments I would like to clarify that the currentOrderList can be any of the paidOrders, pendingOrders, cancelledOrders.
The code for process is the same for all types.
Hm. I see two possibilities here. Either you use some wrapper object such as AtomicReference (might be a bit overpowered because of the multi-threading issues) as the argument and then just set it there or you use a consumer.
In the second case your method would look like this:
public void process(List<OrderStatus> data, Consumer<List<Orders>> target) {
List<Person> newOrders = fromOrderStatus(data);
target.accept(newOrders);
}
Then on the calling side you would implement it like this:
process(data, e-> <<targetList>> = e);
If your list will be wrapped by a different object (for example - AtomicReference), then you will be able to change it.
public static void doSomething(AtomicReference<List<Integer>> listAtomicReference){
List<Integer> newIntegers = new ArrayList<>();
listAtomicReference.set(newIntegers);
}
public static void main(String[] args) {
AtomicReference<List<Integer>> listAtomicReference = new AtomicReference<>(Arrays.asList(4));
doSomething(listAtomicReference);
System.out.println(listAtomicReference.get());
}
Output:
[]
Making a public member variable in a class.
With that being said, I wouldn't recommend walking this path.
Is premature optimization really the root of all evil?

How can I return boolean value using Optional.ifPresent

I have some problems with using Optional.ifPresent statement. I would like to reduce number of NullPointerExceptions, so I decided to use Optional values.
Also I am trying to avoid a ladder of if statements anti-pattern.
So I implemented Optional.isPresent statement. But it's not really that what I expected.
Please look at these listings:
This is a part of my service:
if (getAllComputerProducers().isPresent()) {
if (isComputerProducerAlreadyExist(computerProducer))
return new ResponseEntity<>(HttpStatus.CONFLICT);
}
computerProducerRepository.save(computerProducer);
return new ResponseEntity<>(HttpStatus.CREATED);
getAllComputerProducers function looks like that:
private Optional<List<ComputerProducer>> getAllComputerProducers() {
return Optional.ofNullable(computerProducerRepository.findAll());
}
As you can see, this function returns Optional of List.
The isComputerProducerAlreadyExist function is implemented like that:
private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer) {
return getAllComputerProducers()
.get()
.stream()
.anyMatch(producer -> producer.getProducerName()
.equalsIgnoreCase(computerProducer.getProducerName()));
}
It's so much code and I believe that it could be made simpler.
My target is to reduce code to one line command like:
getAllCimputerProducers().ifPresent(***and-here-some-anyMatch-boolean-function***)
but I can't insert there a function which returns something. How can I do it?
Regards to everyone :)
You could try something like
private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer){
return this.getAllComputerProducers()
.map((List<ComputerProducer> computerProducers) -> computerProducers.stream()
.anyMatch(producer -> producer.getProducerName().equalsIgnoreCase(computerProducer.getProducerName())))
.orElse(Boolean.FALSE);
}
Or instead of loading all computer producers load only the ones using its name.
private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer){
return computerProducerRepository.findByName(computerProducer.getProducerName()).isEmpty();
}
And as far as I know Spring supports also "exist" methods for repositories without even the need to load the Entity.
The following should work
Predicate<ComputerProducer> cpPredicate = producer -> producer.getProducerName()
.equalsIgnoreCase(computerProducer.getProducerName());
boolean compProdExists = getAllCimputerProducers()
.map(list -> list.stream()
.filter(cpPredicate)
.findFirst()))
.isPresent();
You can pass the computerProducer.getProducerName() to repository to get the existing record. Method name will be 'findByProducerName(String producerName)', if producerName has unique constraint, return type will be Optional<ComputerProducer>, else Optional<List<ComputerProducer>>. However, JPA returns empty list instead of null, so optional on list is not required.

retrieving data from db with java streams

I am very new to Java 8 features like streams, filters and stuff and the tell the truth, I haven't been writing in Java for more than a year.
Here is my problem if someone could give a suggestion .
#Override
public ArrayList<Agent> getAllEnabledAgents() throws Exception {
ArrayList<Agent> agents = repository.all(); //redis repository
Stream<Agent> result = agents.stream().filter(a-> a.equals(a.getConfigState().Enabled)); //enum
return result; //I dont know how to return result or whether I am using stream correctly.
}
The main idea is that I want return all enabled agents. gerConfigState() returns an enum (__ConfigState). not sure If am doing this correctly.
Use the collect-metod of the Stream. Also, your filter looks a bit strange, since the variable a is an object of class Agent.
So perhaps something like this:
agents.stream()
.filter(a -> a.getConfigState() == Enabled)
.collect(Collectors.toList());
Then again, like the comment states, you might just be better off filtering this with a query.
Your filter condition is not correct (I assume getConfigState() returns an enum). You can use something like below:
Stream<Agent> streamAgent = agents.stream().filter(a-> a.getConfigState() == Enabled);
return streamAgent.collect(Collectors.toList());
Thanks for the help. This is the final version:
#Override
public List<Agent> getAllEnabledAgents() throws Exception {
return repository.all()
.stream()
.filter(a-> a.getConfigState() == ConfigState.Enabled)
.collect(Collectors.toList());
}

cucumber jvm varargs support in step definition

How to use power of varargs while defining step definitions in cucumber java bindings. I have below step
Given I have following product: prod1, prod2, prod3
My Step definition
#Given("^I have following product [(exhaustive list of products or pattern of the product names)]$")
public void stepDef(String...args)
{
//Process varargs array "args" in here
}
I know workaround can be to except the complete string after colon and then in the code break the string using split(",") and dump it into array. But i just want to know if cucumber on its own supports varargs pattern.
TIA!!!
I dont know if varargs are supported in cucumber, but maybe you can archieve your goal with direct list matchings?
You can define Example Lists in the Feature files in Cucumber
You can define them at the end of a Step:
#Given i want a list
|Entry1|
|Entry2|
Or inline:
#Given i want a list: Entry1, Entry2
Then you can have glue code like:
#Given(^i want a list$)
public void i_want_a_list(List<String> entries) {
//do stuff
}
#Given(^i want a list: (.*)$)
public void i_want_a_list(List<String> entries){
//Do something with the list
}
you can find more info here: https://cukes.info/docs/reference/jvm#step-definitions
If your steps like below-
Given I have following product
|prod1|
|prod2|
|prod3|
Then step definition becomes-
#Given("^I have following product$")
public void i_have_following_product(DataTable dt) throws Exception
{
List<List<String>> outerList = dt.rows();
for(List<String> innerList : outerList)
{
System.out.println(innerLlist.get(0));
}
}

I don't want to write driver.findelement(By.xpath("")) again and again

Hi this is the code below: What I want to do is this build a function in which i just pass the value of XPath, so i don't have to write driver.findElement(By.xpath("")) again and again.
driver.findElement(By.xpath("//*[#id='lead_source']")).sendKeys("Existing Customer");
driver.findElement(By.xpath("//*[#id='date_closed']")).sendKeys("08/07/2013");
driver.findElement(By.xpath("//*[#id='sales_stage']")).sendKeys("Opportuntiy Qualification");
driver.findElement(By.xpath("//*[#id='opportunity_monthly_volume']")).sendKeys("10895");
driver.findElement(By.xpath("//*[#id='probability']")).sendKeys("90");
driver.findElement(By.xpath("//*[#id='opportunity_sales_rep']")).sendKeys("Sales Rep");
driver.findElement(By.xpath("//*[#id='opportunity_sales_regions']")).sendKeys("Northeast");
driver.findElement(By.xpath("//*[#id='opportunity_current_lab']")).sendKeys("Current lab");
driver.findElement(By.cssSelector(Payermixcss +"opportunity_medicare")).sendKeys("5");
The best way would be to use the PageObject pattern. You could do something like this:
public class MyFormPageObject {
public MyFormPageObject enterLeadSource(String value) {
driver.findElement(By.id("lead_source")).sendKeys(value);
return this;
}
public MyFormPageObject enterDateClosed(String value) {
driver.findElement(By.id("date_closed")).sendKeys(value);
return this;
}
//...
}
// then in your test code
myFormPO.enterLeadSource("Existing Customer").enter("08/07/2013");
Note that as mentionned, you should use By.id if you have an identifier, because XPath is slower and not always well supported by all implementation of WebDriver.
Extract a method to upper level and just pass the values as parameters
eg:
yourMethod(Path path) {
driver.findElement(By.xpath(path))
}
As per your concern you can you use page object model and create the method and pass the variable to exact method.. I don't konw java but i know and concepts
private string variable= "Xpath value"
Pass this variable to method and it will interact with POM.. Before that u should know about POM. Then u can easily understand the concepts. Hope it will help full you...
To reduce the amount of code you have to write, you could use a function like this:
private WebElement findElementByXpath(String xpath) {
return driver.findElement(By.xpath(xpath));
}
The first line of your code would be:
findElementByXpath("//*[#id='lead_source']").sendKeys("Existing Customer");
It does not really reduce the length of the code but it only takes one CTRL + SPACE for autocompletion in Eclipse IDE.

Categories

Resources