Two Java strings same value differerent Eclipse ids don't HashMap right - java

Here is the code (class names are from Knime):
HashMap<String,DataColumnSpec> rcols = new HashMap<String, DataColumnSpec>();
rightSpec.forEach(rs -> { rcols.put(rs.getName(), rs); });
DataColumnSpec[] jcols = leftSpec.stream()
.filter(s -> rcols.containsKey(s.getName()))
.toArray(DataColumnSpec[]::new);
The result is empty, but it should not be! There really is one matching column!
Here is the debugger screenshot:
Note P# in the first instance with id=14978 and the second id=666.
What is going on here? What do I do to fix it?

The answer, sad to admit, was a non-printing character in one of the strings. The source of the data is the FileReader node on Knime, and it has a bug handling UTF-8-BOM data files. It injects a NUL character into the first string it reads, which is invisible in the debugger but throws off all the comparisons.
Full credit to #Ole V.V. It just didn't occur to me. Lesson learned!

Related

Java8 : Can't get value of an Optional.of(String) return type

In the context of using the OWLAPI 4.0 API, this following line of code:
ontologyIRI = IRI.create(o.getOntologyID().getOntologyIRI().toString());
returns the following string :
"Optional.of(http://www.indytion.com/music/composition)".
What I need is the sole string "http://www.indytion.com/music/composition".
I tried to declare ontologyIRI as Optional and use .get() method, .orElse(), etc. to no avail. I still have the returned string that includes the 'optional.of()' part.
My question is : How could I get the internal string?
Thank you very much for your help.
Edit : The full code the method
private void LoadOntology(String ontologyPath)
{
OWLOntologyManager man = OWLManager.createOWLOntologyManager();
OWLOntology o;
File ontologyFile = new File(ontologyPath);
Optional<IRI> ontologyIRI;
try {
o = man.loadOntologyFromOntologyDocument(ontologyFile);
ontologyIRI = Optional.of(IRI.create(String.valueOf(o.getOntologyID().getOntologyIRI()).toString()));
System.out.println("Ontology IRI is: " + ontologyIRI.get());
} catch (OWLOntologyCreationException e) {
e.printStackTrace();
}
}
The System.out.println() returns exactly this string:
"Ontology IRI = Optional.of(http://www.indytion.com/music/composition)"
Use .get() instead of toString()
//Returns 'Optional[example]'
Optional.of("example").toString();
//Returns 'example'
Optional.of("example").get();
Short answer: Replace
Optional.of(IRI.create(String.valueOf(o.getOntologyID().getOntologyIRI()).toString()));
with
o.getOntologyID().getOntologyIRI().get();
Longer answer: you're doing an awful lot of back-and forth that's pointless at best and actively harmful in some cases:
In no particular order:
others have already commented that IRI instances are immutable, so creating a new one from an existing one is kind of pointless (if harmless).
calling Optional.of() if you don't intend to actually return an Optional is almost always a bad idea.
String.valueOf() is used to get a string-representation of some value and is usually most useful for debugging, but should not be relied on to fully round-trip everything about an object (the same applies to toString().
So basically what you're left with is this:
o.getOntologyID().getOntologyIRI() gives you an Optional<IRI>
you want an IRI.
Optional::get returns the value contained in the optional, if one exists, so you simply need to call get()
If, however the Optional is empty (i.e. there is no underlying value) then get() will throw a NoSuchElementException. This might or might not be what you want. To work around this either call isPresent() before calling get() to check if a value exists or use any of the multitude of other accessor methods, some of which have "built-in checks" in a way.
Finally, it seems that the problem was not the code itself. This is how the problem has been solved. But I don't understand why it has been solved :
I copy/paste (in the same file) the "shouldAddObjectPropertyAssertions()" example from OWLAPI4 examples -> This example code runs OK (but does not use the getOntologyID() method as I do).
Change SDKs to another minor version '1.8.0_61'
Change again with initial and desired SDK '1.8.0_131'
Invalidate caches and restart the IDE
Problem solved. The exactly same code :
ontologyIRI = o.getOntologyID().getOntologyIRI().get();
System.out.println("Ontology IRI is: " + ontologyIRI);
Now returns the expected string value : "http://www.indytion.com/music/composition" and not "Optional.of(http://www.indytion.com/music/composition)" anymore.
If someone can explain why it has been fixed, I would be very glad.
Thank you again for your help.

Iterating inside a java stream filter

return Arrays.stream(partNumbers.get())
.filter(partNumber -> Objects.nonNull(partNumber.getDescription()))
.filter(partNumber -> partNumber.getDescription().toLowerCase().contains(rateAbbr.toLowerCase()))
.findFirst();
The above code would try to find a partNumber from a list of partNumbers where partNumber's description contains a 'rateAbbr'.
This code worked till 'rateAbbr' was a String but now it is changed to a list of rateAbbrs and I need to find a part number whose description contains any of the rateAbbrs. I tried it with streams and no luck yet. any help is appreciated.
just create a private boolean function that iterates over the list and checks if there is match, then call it inside filter method.

Why my list is empty when I am parsing correct json response?

I am trying to print the ids from a JSON response. But I am not able to understand why I am getting a blank list. I have verified the JSONpath (SECTIONS_IDS_JSONPATH) from the online website and it is giving me correct results.
public static void main(String[] args) {
String SECTIONS_IDS_JSONPATH = "$.[*].instructionEvents[*].sectionId";
String sectionsData = "{\"sections\":[{\"id\":\"8da1cf5d-3150-4e11-b2af-338d1df20475\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":0,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[],\"instructionEvents\":[{\"id\":\"9d0c49e2-1579-43c3-b25a-2f85f551e62d\",\"sectionId\":\"8da1cf5d-3150-4e11-b2af-338d1df20475\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"monday\",\"wednesday\",\"friday\"],\"startTm\":\"2019-01-01T09:45:00-05:00\",\"endTm\":\"2024-12-01T10:45:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]},{\"id\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":20,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[{\"id\":\"c26572de-f9c8-4623-ba6a-79997b33f1c6\",\"sectionId\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"role\":\"primary\",\"persons\":[{\"id\":\"c1b50d79-5505-4a33-9316-b4b1f52c0ca3\",\"names\":[{\"firstName\":\"BanColoFac-1\",\"lastName\":\"CTester\",\"preferred\":true}]}]}],\"instructionEvents\":[{\"id\":\"af8fb500-29f5-4451-95d5-a11215298cd4\",\"sectionId\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"tuesday\",\"thursday\"],\"startTm\":\"2019-01-01T10:00:00-05:00\",\"endTm\":\"2024-12-01T10:50:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]},{\"id\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":20,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[{\"id\":\"808daae1-3ec6-47ec-9af0-5392199bdf78\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"role\":\"primary\",\"persons\":[{\"id\":\"793cc9b3-57c7-4a2d-8984-07a1fb6834a9\",\"names\":[{\"firstName\":\"Andrew\",\"lastName\":\"Adams\",\"preferred\":true}]}]}],\"instructionEvents\":[{\"id\":\"730b4206-684d-4413-bf20-9bec5c1dc900\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"tuesday\",\"thursday\"],\"startTm\":\"2019-01-01T10:00:00-05:00\",\"endTm\":\"2024-12-01T10:50:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"},{\"id\":\"8bc059ab-a8f8-4469-8e79-bbc71f7fa3fd\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"monday\",\"wednesday\",\"friday\"],\"startTm\":\"2019-05-26T09:00:00-04:00\",\"endTm\":\"2021-05-26T09:50:00-04:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]}]}";
List<String> ids = JsonPath.parse(sectionsData).read(SECTIONS_IDS_JSONPATH);
System.out.println(ids);
}
Alright, since this question might get delete if nothing else ever happens I better post this as an answer.
As explained by Andreas you should use JSONPath $.*[*].instructionEvents[*].sectionId instead. Quoting fromt the comment
The syntax $.[*] is undefined, I can't find any documentation/example
doing that. The JSONPath Online Evaluator [*based on
JSONPath-Plus implemented in JavaScript] treats it as $..[*], but the Java library treats
it differently. Since the outer part of the JSON is {"sections":[ ... ]}, you have an object, so you need a property selector (.prop or
.*). Once you've selected your property (.sections, or .*
since there's only one), the property is an array, so you need an
array selector ([2] or [*]). Hence you can use $.sections[*] or
$.*[*] to match all sections.
Indeed, looking at this massive JSONPath Comparision we can see that the syntax in question is not listed for any implementation.

Comparing file name to string

I have hit a road block in a program I am writing in Java. The program basically copies folders and files from multiple locations into one folder to make backing up code from multiple locations on my computer easier. The problem I have is that I don't want to copy specific folders, in this case "workspace/.metadata". The start of the code I am having issues with is below:
public void copyFolder(File in, File out, String loc)
throws IOException{
String check = in.getName().substring(1);
System.out.println("loc:"+loc+"check: "+check);
if(loc.equals("java")){
if(check.equals("metadata")){
System.out.println("failboat");
//statusBox.append("failboat");
}
}
And this is the result I see:
loc:java
check: orkspace2
loc:java
check: metadata
loc:java
check: lock
I've had other's look at the code and they agree it should work. I've even created a replica of the code in a test file:
String test = "fmetadata";
String loc = "java";
String check = test.substring(1);
if(loc.equals("java")){
if(check.equals("metadata")){
System.out.print("failboat");
}else{
System.out.println("WTF");
System.out.print(test+ ": :"+check);
}
}
And the result?
failboat
There is a dent in my desk the size of my forehead from trying to figure this out.
If that output you posted is the actual output:
loc:java
check: orkspace2
loc:java
check: metadata
loc:java
check: lock
It does not match the code you've pasted, as you do not print a newline between the two items:
System.out.println("loc:"+loc+"check: "+check);
If this is truly what you are seeing with that code then I would say the problem is that loc has a stray newline at the end, and is actually "java\n" rather than "java" as you expect. So you should go back and examine how you generate the value you pass through loc to begin with before calling that function.
If this is the case, some suggestions for diagnostics improvements that could help you notice these kinds of issues sooner (in addition to stepping through with a debugger):
// quote your strings to spot whitespace, print length to spot unexpected
// unprintable characters.
System.out.println("loc: \""+loc+"\" "+loc.length());
System.out.println("check: \""+check+"\" "+check.length());
And:
if(loc.equals("java")){
// make sure you're getting to this point, don't assume that the first
// if condition was satisfied:
System.out.println("grumpycat"); // <----
if(check.equals("metadata")){
System.out.println("failboat");
}
}

Replace tags in a word file

I've some tags in a word file which looks like <tag>.
Now I get the content of the Word file with docx4j and loop through every line and search for this tag. When I find one, then i replace it with a String. But this code i tried doesn't work and now i really don't know how i can realise it!
Here's the code i've already tried:
WordprocessingMLPackage wpml = WordprocessingMLPackage.load(new File(path));
MainDocumentPart mdp = wpml.getMainDocumentPart();
List<Object> content = mdp.getContent();
String line;
for (Object object : content) {
line = object.toString();
if (line.contains("<tag>")) {
line.replace("<tag>", "<newTag>");
}
}
Any tips or solutions how i can achieve it?
One of your problems is that you modify String line which has no effect on anything. line.replace("<tag>", "<newTag>"); result of this operation is ignored. you would definitely want to do sth with that, right?
Also, if object in your loop is not an instaneOf String, then line and object are pointing to different objects.
You need to modify contents but not the way you're doing this. Please read getting started
Also there are lots of examples (sample code) in source code download section
If you have any concrete problems after reading the getting started, we'll be happy to help you.
The things in your List will be org.docx4j.wml.P (paragraphs), or Tbl (tables) or other block level content.
Paragraphs contain runs, which in turn contain the actual text.
For the suggested way of doing what you want to do, see the VariableReplace sample.
Better yet, consider content control data binding.
Otherwise, if you want to roll your own approach, see the Getting Started guide for how to traverse, or use JAXB-level XPath.
First you should use replaceAll() instead of replace().
Then you should store this String into an object you can serialize back after modification to the Word file.
Furthermore I think that it would also be good to handle closing tags (if there some) ...
String (line) is immutable, therefore replace("<tag>", "<newTag>") does not modify your line it creates a new modified one.
Your code shoudl do something like this:
for (Object object : content) {
line = object.toString();
if (line.contains("<tag>")) {
line= line.replaceAll("<tag>", "<newTag>");
}
writeLineToNewFile(line);
}
or shorter:
for (Object object : content) {
writeLineToNewFile(object.toString().replace("<tag>", "<newTag>");
}

Categories

Resources