I please bear with me, I have been using Java for 2 days and i've hit a bit of a hurdle.
I am using Talend to perform a count using the tMemorize and tJava components but this may be a question for a Java developer. I have previously posted an issue with using this method within a joblet by my new issue is more Java related which can be viewed here:
using Joblets in talend with tMemorize and tJavaFlex
I need to reference an array generated by the java code talend. I cannot reference this element directly because of an issue with using tJavaFlex within multiple joblets: Java renames joblets each time they are used.
It may be useful to understand how my code works in normal circumstances (excluding the use of joblets).
int counter = 1;
if (EnquiryID_mem_1_tMemorizeRows_1[0].equals(EnquiryID_mem_1_tMemorizeRows_1[1]))
{
counter++;
}
row3.counter = counter;
The EnquiryID_mem_1_tMemorizeRows_1[0] and EnquiryID_mem_1_tMemorizeRows_1[1] is what I need to reference.
To overcome this I have written the following code.
String string = currentComponent;
String[] parts = string.split("_");
String part1 = parts[0];
String part2 = parts[1];
String joblet = part1+'_'+part2;
String newrow = "EnquiryID_"+joblet+"_tMemorizeRows_1"
if (newrow[0].equals(newrow[1]))
{
counter++;
}
row3.counter = counter;
However I get the following error:
The type of the expression must be an array type but it resolved to String
I understand that the newrow variable is a string and I am using it to reference an array. I have searched far and wide online for a resolve but I cannot fine one. Can someone help me please?
Thank you
Here is the talend code that my code should reference. I have taken it from the currentComponent that I am using to when it changes to one not in use directly.
currentComponent = "mem_1_tMemorizeRows_1";
// row1
// row1
if (execStat) {
runStat.updateStatOnConnection("row1" + iterateId,
1, 1);
}
for (int i_mem_1_tMemorizeRows_1 = iRows_mem_1_tMemorizeRows_1 - 1; i_mem_1_tMemorizeRows_1 > 0; i_mem_1_tMemorizeRows_1--) {
EnquiryID_mem_1_tMemorizeRows_1[i_mem_1_tMemorizeRows_1] = EnquiryID_mem_1_tMemorizeRows_1[i_mem_1_tMemorizeRows_1 - 1];
}
EnquiryID_mem_1_tMemorizeRows_1[0] = row1.EnquiryID;
mem_1_row2 = row1;
tos_count_mem_1_tMemorizeRows_1++;
/**
* [mem_1_tMemorizeRows_1 main ] stop
*/
/**
* [mem_1_tJavaFlex_1 main ] start
*/
currentComponent = "mem_1_tJavaFlex_1";
// mem_1_row2
// mem_1_row2
if (execStat) {
runStat.updateStatOnConnection("mem_1_row2"
+ iterateId, 1, 1);
}
mem_1_row3.QuoteID = mem_1_row2.QuoteID;
mem_1_row3.EnquiryID = mem_1_row2.EnquiryID;
if (EnquiryID_mem_1_tMemorizeRows_1[0]
.equals(EnquiryID_mem_1_tMemorizeRows_1[1])) {
rower++;
}
mem_1_row3.rower = rower;
tos_count_mem_1_tJavaFlex_1++;
/**
* [mem_1_tJavaFlex_1 main ] stop
*/
/**
* [mem_1_tMap_1 main ] start
*/
currentComponent = "mem_1_tMap_1";
Thank you to everyone who has helped so far.
This
if (newrow[0].equals(newrow[1]))
Tries to pick the first and second element of the array newrow. Unfortunately you declare newrow as
String newrow = "EnquiryID_"+joblet+"_tMemorizeRows_1"
which is not an array but a String. That syntax in the if will not work with a String. I am not sure what you are trying to do but that if check will not work.
EDIT:
If you are trying to pick up char from a string you need to use charAt(index).
If you want to treat newrow as an array you have to declare it as such and pass appropriate elements to it.
EDIT 2: I think you are trying to pass the actual data in joblet to newrow in this:
String newrow = "EnquiryID_"+joblet+"_tMemorizeRows_1"
But what happens here is that everything is concatenated in one String so you need to figure out where the data you are looking for (part[0] and part[1] I assume) is present in that String so you can pull them out (basically what indices contain the values you are looking for).
An example of how newrow will look after that assignment:
"EnquiryID_part1_part2_tMemorizeRows_1"
So "part1" will start at index 10 and will end at index 14. I am just using "part1" here, but it would have whatever value is stored in part1 variable.
If you can show us what you expect it to look like that would help.
I'm not super familiar with talend (understand: not at all). But it sounds like you have some sort of attribute of a generated class (say myGeneratedObject) and you want to access it by name.
In that case, you could do something like:
String newrow = "EnquiryID_"+joblet+"_tMemorizeRows_1"
Field field = myGeneratedObject.getClass().getField(newrow);
if (field.getClass().isArray()) {
if(Array.get(field, 0).equals(Array.get(field, 1)) {
counter++;
}
}
It all depends how you access that field really and where it's declared. But if it's an attribute of an object, then the code above should work, +/- contextual adjustments due to my lack of knowledge of the exact problem.
Related
I'm experimenting with Hunspell and how to interact with it using Java Project Panama (Build 19-panama+1-13 (2022/1/18)). I was able to get some initial testing done, as in creating a handle to Hunspell and subsequently using that to perform a spell check. I'm now trying something more elaborate, letting Hunspell give me suggestions for a word not present in the dictionary. This is the code that I have for that now:
public class HelloHun {
public static void main(String[] args) {
MemoryAddress hunspellHandle = null;
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
var allocator = SegmentAllocator.nativeAllocator(scope);
// Point it to US english dictionary and (so called) affix file
// Note #1: it is possible to add words to the dictionary if you like
// Note #2: it is possible to have separate/individual dictionaries and affix files (e.g. per user/doc type)
var en_US_aff = allocator.allocateUtf8String("/usr/share/hunspell/en_US.aff");
var en_US_dic = allocator.allocateUtf8String("/usr/share/hunspell/en_US.dic");
// Get a handle to the Hunspell shared library and load up the dictionary and affix
hunspellHandle = Hunspell_create(en_US_aff, en_US_dic);
// Feed it a wrong word
var javaWord = "koing";
// Do a simple spell check of the word
var word = allocator.allocateUtf8String(javaWord);
var spellingResult = Hunspell_spell(hunspellHandle, word);
System.out.println(String.format("%s is spelled %s", javaWord, (spellingResult == 0 ? "incorrect" : "correct")));
// Hunspell also supports giving suggestions for a word - which is what we do next
// Note #3: by testing this `koing` word in isolation - we know that there are 4 alternatives for this word
// Note #4: I'm still investigating how to access individual suggestions
var suggestions = allocator.allocate(10);
var suggestionCount = Hunspell_suggest(hunspellHandle, suggestions, word);
System.out.println(String.format("There are %d suggestions for %s", suggestionCount, javaWord));
// `suggestions` - according to the hunspell API - is a `pointer to an array of strings pointer`
// we know how many `strings` pointer there are, as that is the returned value from `suggest`
// Question: how to process `suggestions` to get individual suggestions
} finally {
if (hunspellHandle != null) {
Hunspell_destroy(hunspellHandle);
}
}
}
}
What I'm seeing is that a call to Hunspell_suggest (created from jextract) succeeds and gives me back (4) suggestions (which I verified using Hunspell from the commandline) - so no problem there.
What is more challenging for me now is how do I unpack the suggestions element that comes back from this call? I've been looking at various examples, but none of them seem to go into this level of detail (and even if I find examples, they seem to be using outdated panama APIs).
So in essence, here is my question:
How do I unpack a structure that reportedly consists of a pointer to an array of strings pointer using panama JDK19 APIs to their respective collection of strings?
Looking at the header here: https://github.com/hunspell/hunspell/blob/master/src/hunspell/hunspell.h#L80
/* suggest(suggestions, word) - search suggestions
* input: pointer to an array of strings pointer and the (bad) word
* array of strings pointer (here *slst) may not be initialized
* output: number of suggestions in string array, and suggestions in
* a newly allocated array of strings (*slts will be NULL when number
* of suggestion equals 0.)
*/
LIBHUNSPELL_DLL_EXPORTED int Hunspell_suggest(Hunhandle* pHunspell,
char*** slst,
const char* word);
The slst is a classic 'out' parameter. i.e. we pass a pointer to some value (in this case a char** i.e. an array of strings), and the function will set this pointer for us, as a way to return multiple results. (the first result being the number of suggestions)
In panama you use 'out' parameters by allocating a segment with the layout of the type the parameter is a pointer of. In this case char*** is a pointer to char**, so the layout is ADDRESS. We then pass the created segment to the function, and finally retrieve/use the value from that segment after the function call, which will have filled in the segment contents:
// char***
var suggestionsRef = allocator.allocate(ValueLayout.ADDRESS); // allocate space for an address
var suggestionCount = Hunspell_suggest(hunspellHandle, suggestionsRef, word);
// char** (the value set by the function)
MemoryAddress suggestions = suggestionsRef.get(ValueLayout.ADDRESS, 0);
After that, you can iterate over the array of strings:
for (int i = 0; i < suggestionCount; i++) {
// char* (an element in the array)
MemoryAddress suggestion = suggestions.getAtIndex(ValueLayout.ADDRESS, i);
// read the string
String javaSuggestion = suggestion.getUtf8String(suggestion, 0);
}
I'm very new to java and coding in general, so I apologize if this is a simple thing. I want to know if it's possible to add a variable within a string that will be randomized when the item itself is chosen from the ArrayList of options.
I've already created the objects, put them in an ArrayList, and have a method that randomly calls indices from the ArrayList and prints their attributes. However, some (not all) I would like to randomize a part of the "name" attribute from another separate Array. Is there a way to do this? If possible, I'd like it to be randomized each time its called, so in the case that I call that particular object twice from the ArrayList, its "name" attribute would not be identical (unless by chance the same suffix is called from the random name Array twice).
//Doesn't need randomization
Item r1 = new Item("Static Name", 1000);
// (X) needs to be either "Title", "Callsign", or "Identifier"
Item r2 = new Item("Random (X)", 500);
UPDATE:
I followed DevilsHnd's suggestion, but it doesn't seem to replace anything.
//declared in class
String[] suffix = {"Title","Callsign","Nickname"};
//as part of toString()
if (name.contains("(X)")) {
name.replace("(X)", [new Random().nextInt(((suffix.length - 1) - 0) + 1) + 0]);
My toString still prints out "Random (X)" instead of a desired "Random Title".
I am able to get it to work if I remove the if function and use a static value for the replacement, like name = name.replace("(X)","Title");, but I still can't figure out how to get it to replace it with a value from the suffix array.
I'm not sure if I get what you mean but you may get an idea from the following:
String[] attributes = {"Title", "Callsign", "Identifier"};
String itemString = "Random (X)";
if (itemString.contains("(X)")) {
itemString = itemString.replace(
"(X)",
attributes[new Random().nextInt(((attributes.length - 1) - 0) + 1) + 0]
);
}
System.out.println(itemString);
Item r2 = new Item(itemString, 500);
Tried changing around the for loop condition several times, still get ArrayIndexOutOfBounds when I pass zero as a parameter. Every other number works fine, I am trying to account for zero by setting it equal to zero automatically, am I doing that part incorrectly? Everything compiles and runs fine except for zero.
private static int iterativeCalculation(int userEntry)
{
int iterativeArray[] = new int[userEntry + 1];
iterativeArray[0] = 0;
iterativeArray[1] = 1;
for (int i = 2; i <= userEntry; i++)
{
iterativeArray[i] = (3 * iterativeArray[i - 1]) - (2 * iterativeArray[i - 2]);
iterativeEfficiencyCounter++;
}
return iterativeArray[userEntry];
}
public static void main(String[] args) {
System.out.println(iterativeCalculation(0));
}
Tried debugging my way through the code, still not understanding what is going wrong. Would appreciate any help! Thanks!
When you pass zero as parameter, userEntry + 1 = 1.
But here:
iterativeArray[1] = 1;
You are trying to set the second element's value. Remember that length of array is one less than its actual size. So removing this line will fix it. Or use userEntry + 2 instead and alter your loop accordingly.
EDIT:
If you really want to fix first and second element, then use this instead:
int iterativeArray[] = new int[userEntry + 2];
iterativeArray[0] = 0;
iterativeArray[1] = 1;
This will create an array of adequate base size.
And remember, length you enter in [...] while creating array has to be one more than the actual length you want. Because actual array starts counting from 0.
In your case, you were setting length as 1 (minimum). That would create an array which can store only one element; that is iterativeArray[0] = //something. Anything above that is OutOfBounds.
You are setting iterativeArray[1] = 1; regardless of whether or not there are actually 2 or more items in the array. That will be out of bounds with one element.
I think you should step through the code in debugger to best understand what the problem is. You'll see exactly where it's got a problem if you single-step through the code. This is a fundamental technique and tool.
Is it possible to know/get how much space/memory are used when a method is executed or when there is a return value? I don't want to know how much space used by the app, just some code like method or the return value. I tried the runtime.getRuntime, but from my understanding, It looks like it tells me how much space is used by the entire code/app, am I right?
EDIT :
public int [] randtotal(int times2)
{
int in1[] = new int[times2];
for (int i = 0; i<Num2; i++)
Random rand = new Random();
{
in1[times2]= rand.NextInt(5);
}
totalNum(in1);
return int1;
}
As you can see here, at the end of the code there is the "return int1;" , so I want to know when these code is executed how much space is allocated for the value here?
You can use Visualvm tool to profile the overall application and you can also profile certain package, class or function
see this link :
https://visualvm.java.net/profiler.html
I'm trying to get a program so that it loops and adds up the sum of an array. My code appears to be working, with the exception that it states that the text[j] in adding = adding + text[j] is an incompatible type (I'm assuming data type). Earlier in the code, I have int adding = 0;. This is the erroneous code:
for (int j=0;j<=total;j++){
adding = adding + text[j];
System.out.println(text[j]);
}
where total is the limiting factor. If I put:
for (int j=0;j<= total;j++){
adding = adding + j;
System.out.println(text[j]);
}
the program compiles but gives 45, which is incorrect.
Why is this happening? Thanks!
The answer actually turned out to be outside the code given. I had set my array to be a String, not an int as it should have been.
If your text[] is String[] or char[] as the name suggests then I believe you are trying to update text[] elements with suffix j or adding, which you can write as:
If it is char[] then write
text[j] = (char)(adding + (int)text[j]);
If it is String[] then write
text[j]= text[j]+adding;
as required. It all depends on what is the data type of text[] and what are you trying to achieve?
Also as suggested in one of the answers, if total is length of the array, then change the comparison to < to avoind ArrayIndexOutOfBoundsException
Your second example, adds j into adding but prints text[j] value, which is nothing to do with the addition of adding and j.