Can some one tell me please what is wrong here. My code is fine until I added this portion of code if (!tmp.isEmpty()) { return e.isEmpty(); }
The error is: Cannot resolve method startsWith(java.lang.String)
#Test
public void TestData() {
ArrayList<String> rootOpts = new ArrayList<String>();
rootOpts.add("aa");
rootOpts.add("bb");
rootOpts.add("ac");
ArrayList<String> allSiblings = new ArrayList<String>();
allSiblings.add("aa");
allSiblings.add("ac");
allSiblings.add("abc");
System.out.println("allMatch " + rootOpts.stream()
.map((e) -> {
System.out.println("e = " + e);
List<String> tmp = new ArrayList<String>();
tmp.addAll(allSiblings);
String[] CHs = {"ab","aa","ac"};
for (String chh : CHs) {
tmp.remove(chh);
}
if (!tmp.isEmpty()) {
return e.isEmpty();
}
return e;
})
.anyMatch(v -> v.startsWith("a")));
}
I am trying to rewrite the following code below(this code is contained in a method that is supposed to return a boolean value true or false):
for (Option e : rootOpts) {
List<String> tmp = new ArrayList<String>();
tmp.addAll(allSiblings);
if (e.getData() != null && !e.getData().getString().isEmpty()) {
String[] chs = {"ab","aa","ac"};
for (String ch : chs) {
tmp.remove(ch);
}
} else {
return false;
}
if (!tmp.isEmpty()) {
return false;
}
}
return true;
Thank you for your help guys
e.isEmpty() returns a boolean. In the following method anyMatch you want to invoke the method startsWith on this boolean but this method does not exist on boolean. So change your code to:
if (!tmp.isEmpty()) {
return ""; //or whatever string makes sense
}
e is of type String while e.isEmpty() is of type Boolean.
Therefore the return type of your function is Object.
Finally, Object does not have a startsWith function, contrary to the original String type that was returned which is why the compiler is complaining.
Look at the return type of isEmpty() - it's boolean. How are you planning to do startsWith on a boolean true/false? :) Stream predicts that it's possible to get boolean, and thus it cannot let you do startsWith on it.
if (!tmp.isEmpty()) {
return e.isEmpty();
}
Related
I have a class like this:
public static class TiposDeHistorial
{
String CODIGO, TIPO;
public TiposDeHistorial()
{
}
public String getCODIGO()
{
return CODIGO;
}
public void setCODIGO(String CODIGO)
{
this.CODIGO = CODIGO;
}
public String getTIPO()
{
return TIPO;
}
public void setTIPO(String TIPO)
{
this.TIPO = TIPO;
}
}
and a list of it:
ArrayList<TiposDeHistorial> tiposHistorial;
So my question is: can I use tiposHistorial.contains(...) to search in a specific array field, CODIGO or TIPO, for example?
First of, you do not have an array but an ArrayList.
The contains method on a List operates with the equals method of it's stored elements (TiposDeHistorial in your case). Therefore the answer to your question is no.
Trying something like tiposHistorial.contains("a") will not work as there is a type mismatch: your list is of type TiposDeHistorial while you try to check for an element of String.
If you are using Java 8 you can use following code:
tiposHistorial.stream()
.filter(x -> "specific value for CODIGO".equals(x.getCODIGO()))
.findFirst()
.orElse(null);
It will return TiposDeHistorial object in the list containing specific CODIGO value or null otherwise.
As for your question: "contains" method just returns "true" or "false", not an object. Moreover it uses "equals" method of your object, so it will not help if you want to search using fields.
Contains method will return true only if your object equals with ur list elements objects.
You can try extending equals method and have your own criteria which can work for either CODIGO or TIPO.
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
test other = (test) obj;
if (CODIGO == null) {
if (other.CODIGO != null)
return false;
} else if (!CODIGO.equals(other.CODIGO))
return false;
return true;
}
The answers already given here are all correct, just if You don't know java streams, and would like to check if the list contains both some CODIGO and TIPO fields, for me the simplest solution would be:
ArrayList<TiposDeHistorial> tiposHistorial = new ArrayList<>();
//add elements to the list
String tipo = "TIPO"; // the TIPO value You are looking for in the list
String codigo = "CODIGO"; // the CODIGO value You are looking for in the list
boolean containsTipo = false;
boolean containsCodigo = false;
for (TiposDeHistorial element: tiposHistorial) {
if (!containsTipo && element.getTIPO().equals(tipo)) {
containsTipo = true;
}
if (!containsCodigo && element.getCODIGO().equals(codigo) ){
containsCodigo = true;
}
if (containsTipo && containsCodigo)
break;
}
By editing it just a bit, You may also find which elements of the array contain the values You are looking for, if that will be Your intention
I keep finding methods having code like this:
public boolean checkSomethingForCollection(Collection<Something> things){
for(Something thing:things){
boolean satisfiesCondition = check(thing);
if(satisfiesCondition){
return true;
}
}
return false;
}
private static boolean check(Something something){
//omitted...
}
I am fully aware of the fact that the public method will stop by reaching 'return' if the check(..) returns true, but it still looks ugly to me.
What would be preferable? Using break; instead to have one return only, or refactor to something else? Having
if(booleanExpression){
return true;
}
just makes me sick.
You can't do that with a "java for each", but you can avoid it with a normal for like this :
boolean satisfiesCondition = false;
for (int i = 0; i < size && !satisfiesCondition; ++i) {
satisfiesCondition = check(things[i]);
}
return satisfiesCondition;
Java streams in Java 8 make this pretty easy - the Stream.anyMatch method taking a predicate is exactly what you want. In this case you can use a method reference to create a predicate from the check() method.
public boolean checkSomethingForCollection(Collection<Something> things) {
return things.stream().anyMatch(this::check);
}
Here's a short but complete example:
import java.util.*;
public class Test {
private final int minLength;
private Test(int minLength) {
this.minLength = minLength;
}
public boolean checkAny(Collection<String> things) {
return things.stream().anyMatch(this::check);
}
private boolean check(String x) {
return x.length() >= minLength;
}
public static void main(String[] args) throws Exception {
Test t = new Test(5);
List<String> shortStrings = Arrays.asList("asd", "bcd", "foo");
List<String> mixedStrings = Arrays.asList("asd", "bcd", "this is long", "foo");
System.out.println(t.checkAny(shortStrings)); // false
System.out.println(t.checkAny(mixedStrings)); // true
}
}
I haven't checked the code, but you should be able to do something like this:
things.stream()
.filter(x -> check(x))
.findFirst()
You can find some more information here.
Since the for makes use of an iterator, you could opt to use a while loop instead:
Iterator<Something> iter = things.iterator();
boolean isValid= false;
while(iter.hasNext() && !isValid)
isValid = check(iter.next());
return isValid;
That being said, I think that your current version of things is more readable.
I have the following code where the Binding.createStringBinding(...) part is going to be repeated many many times, the only difference is the method used, i.e. getA(), getB() , getC()
this.attributeA.bind(Bindings.createStringBinding(() -> {
if(webService.getLastValue() != null){
return webService.getLastValue().getA();
} else{
return "";
}
}, webService.lastValueProperty()));
this.attributeB.bind(Bindings.createStringBinding(() -> {
if(webService.getLastValue() != null){
return webService.getLastValue().getB();
} else{
return "";
}
}, webService.lastValueProperty()));
New:
This is the part of the code that I want to make reusable:
Bindings.createStringBinding(() -> {
if(webService.getLastValue() != null){
return webService.getLastValue().getB();
} else{
return "";
}
}, webService.lastValueProperty())
How can I make this reusable? Perhaps making this a function ?
Maybe something like this:
private Binding createBinder(final Supplier<String> lambda) {
return Bindings.createStringBinding(() -> {
if(webService.getLastValue() != null){
return lambda.get();
} else{
return "";
}
}
}
called like
this.attributeA.bind(createBinder(() -> webService.getLastValue().getA()), webService.lastValueProperty());
this.attributeB.bind(createBinder(() -> webService.getLastValue().getB()), webService.lastValueProperty());
A slight variation on #Joshua's answer. Here ObjectTest is the type returned by webService.getLastValue().
private void makeBinding(StringProperty property, Function<ObjectTest, String> propertyAccessor) {
property.bind( Bindings.createStringBinding(() -> {
ObjectTest lastValue = webService.getLastValue();
if (lastValue == null) {
return "" ;
} else return propertyAccessor.apply(lastValue);
}, webService.lastValueProperty()) );
}
And now you do
makeBinding(attributeA, ObjectTest::getA);
makeBinding(attributeB, ObjectTest::getB);
etc
Let's suppose attributeA and attributeB both implement the Property<String> interface, and that methods getA, getB, etc. all return a String. With this in mind, you could do:
BiConsumer<Property<String>, Function<ObjectTest, String>> binder =
(property, getter) ->
property.bind(Bindings.createStringBinding(() -> {
if (webService.getLastValue() != null) {
return getter.apply(webService.getLastValue());
} else {
return "";
}
}, webService.lastValueProperty()));
This code creates a BiConsumer (which is a consumer that takes 2 arguments).
The first argument is an instance of Property<String> (as suggested by #James_D's comment) that is implemented by attributeA and attributeB.
The second argument is a Function<ObjectTest, String>, which is a function that takes an instance of ObjectTest and returns a String. Here I'm using it to represent a generic getter method over the ObjectTest class (more specifically, ObjectTest::getA and ObjectTest::getB).
If you want, you could rewrite the `BiConsumer' in a more java8 friendly way:
BiConsumer<Property<String>, Function<ObjectTest, String>> binder =
(property, getter) ->
property.bind(Bindings.createStringBinding(
() -> Optional.ofNullable(webService.getLastValue())
.map(getter).orElse(""),
webService.lastValueProperty()));
To use it:
binder.accept(this.attributeA, ObjectTest::getA);
binder.accept(this.attributeB, ObjectTest::getB);
The code above assumes that methods getA, getB, etc. return a String.
You might want to further read about Optional and BiConsumer in the javadocs.
My Java code look as below;
public List<Lookup> findAll(List<String> types, String lang) {
Query query = entityManager.createNamedQuery("Lookup.myQuery");
List<Lookup> result = new ArrayList<Lookup>();
for (String type : types) {
// check if isValidLookupTypeOrCode(type) && isValidLang(lang))
// if yes, do query.setParameter("lookupTypes", types) & query.setParameter("lang", lang);
// result = query.getResultList();
}
return result;
}
private boolean isValidLookupTypeOrCode(String s) {
String pattern = "^[a-zA-Z0-9\\_]*$";
if (s.matches(pattern)) {
return true;
}
return false;
}
private boolean isValidLang(String s) {
String pattern= "[a-zA-Z]{1,3}$";
if (s.matches(pattern)) {
return true;
}
return false;
}
Now how do I update the code inside my findAll() method, as I need to check if each of the string inside List types passes the regex (isValidLookupTypeOrCode) and the single string lang also passes the regex (isValidLang)
What is the best way to check for the 2 conditions ? since isValidLang() needs to be actually checked just once, but isValidLookupTypeOrCode() needs to be run on each string of the list ?
You can do:
public List<Lookup> findAll(List<String> types, String lang) {
List<Lookup> result = new ArrayList<Lookup>();
// validate lang parameter
if (isValidLang(lang)) {
// validate each of the type parameters from list
for (String type : types) {
if ( !isValidLookupTypeOrCode(type) )
return result;
}
// we are here, all good so run the query
Query query = entityManager.createNamedQuery("Lookup.myQuery");
query.setParameter("lookupTypes", types);
query.setParameter("lang", lang);
result = query.getResultList();
}
return result;
}
If you are able to use Java 8 then this is a good use case for streams:
if (isValidLang(lang)
&& types.stream().allMatch(MyClass::isValidLookupTypeOrCode)) {
...
}
I am new to Java,
Here is my code,
if( a.name == b.name
&& a.displayname == b.displayname
&& a.linkname == b.linkname
......... )
return true;
else
return false;
I will call this method and have to check that all properties of objects 'a' and 'b'.
Each object will have more than 20 properties. So, it is will be tidy if i use if case for each property.
An exception is throwed if the return is false and I have to report which property fails.
Is there any easy method to find where the condition fails within the if case.
Pls help. Ask if you are not clear about the question.
The question is, would you like to continue checking if one of the conditions fails?
You could do something like comparator where you have interface:
public interface IComparator {
boolean compare(YourObject o1, YourObject o2);
String getComparatorName();
}
Next you create set of implementations of that interface:
NameComparator implements IComparator {
private name="Name Comparator";
#Override
public boolean compare(YourObject o1, YourObjecto2) {
return o1.getName().equals(o2.getName());
}
#Override
public String getComparatorName() {
return name;
}
}
Next you store set of these comparators in arrayList and you iterate through them and record which one fails by adding them to some other collection.. Hope that helps!
For instance you create array:
IComparator[] comparators = new IComparator[]{ new NameComparator, new DisplayNameComparator};
List<IComparator> failedComparationOperations = new ArrayList<IComparator>();
for(IComparator currentComparator : comparators) {
if(!currentComparator.compare(o1, o2)) {
failedComparationOperations.add(currentComparator);
}
}
for(IComparator currentComparator: failedComparationOperations)
{
System.out.println("Failed Comparation at: "+currentComparator.getComparatorName());
}
You may use reflection: browse what fields are defined, and check each of them using method equals. Print error message if they're not equal, give summary at the end.
boolean equals = true;
Field[] fields = a.getClass().getDeclaredFields();
for (Field f: fields){
f.setAccessible(true);
try {
if (!f.get(a).equals(f.get(b))){
System.out.println(f.getName() + ": " + f.get(a) + "!="+ f.get(b));
equals = false;
};
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("equals?: " + equals);
If you need to know which of the conditions has failed you should check each of the conditions independently.
It might be a little overkill if you are dealing with this single requirement, but what about the Strategy Design Pattern?
http://sourcemaking.com/refactoring/replace-conditional-with-polymorphism
It should be an interesting option if you have other business rules that you can combine with this check.
If a and b are instances of the same class, let's assume A, and the fields are visible, then you can use reflections:
for (Field f : A.class.getFields()) {
try {
if (!f.get(a).equals(f.get(b))) {
throw new RuntimeException("Field " + f.getName() + " is different.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
Without reflection you can't get maximum conciseness, but the followincg can help you to some extent. Make this kind of class:
class NamedEquals {
final String name;
final Object left, right;
NamedCondition(String name, Object left, Object right) { ...assign them... }
boolean areEqual() { return left.equals(right); }
}
Then make a List<NamedEquals>:
List<NamedEquals> conds = Arrays.asList(
new NamedEquals("name", left.name, right.name),
new NamedEquals("displayname", left. displayname, right.displayname),
...
);
And you can find if some of them fail:
for (NamedEquals eq : conds)
if (!eq.areEqual()) throw new ValidationException(eq.name);
Using a factory method can shorten the construction code:
static NamedEquals eq(String name, Object left, Object right) {
return new NamedEquals(name, left, right);
}
With that you can have
List<NamedEquals> conds = Arrays.asList(
eq("name", left.name, right.name),
eq("displayname", left. displayname, right.displayname),
...
);
How about?
// Adapted from your example:
if(!equalTo(a.name, b.name))
fail("name");
if(!equalTo(a.displayname, b.displayname))
fail("displayname");
... etc ...
...
// Allow for null values.
public boolean equalTo(Object a, Object b) {
return a != null ? a.equals(b) : b == null;
}
public void fail(String which) throws SomeException {
throw new SomeException("Failed on '"+which+"'!");
}
Another possible might be to turn each object into a Map<String,?>, perhaps by adding a Map<String,?> toMap() method to the value object, and implementing this by constructing a new map and dumping the value's fields into it. Then you can get the maps and do equals() on them.