I have created an array of values from my SQLite database - this comprises of just two values from two different columns from an inner joined table.
in my SQLDatabaseHelper.java:
public List<List<String>> getAllAnswersByQuestion1() {
List<String> array1 = new ArrayList<String>();
List<String> array2 = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase();
String selectQuery = "SELECT * FROM " + TABLE_ANSWERS + " ta, "
+ TABLE_QUESTION + " tq, " + TABLE_QUESTANS + " tqa WHERE ta." + ASID
+ " = " + "tqa." + ASID + " AND tq." + QID + " = "
+ "tqa." + QID;
Cursor c = db.rawQuery(selectQuery, null);
if (c.moveToFirst()) {
do {
String questdescr = c.getString(c.getColumnIndex(QDESCR));
String questid = c.getString(c.getColumnIndex(QID));
array1.add(questdescr);
array2.add(questid);
} while (c.moveToNext());
}
List< List<String> > listArray = new ArrayList< List<String> >();
listArray.add(array1);
listArray.add(array2);
return listArray;
}
I want to pass these to my main activity. Specifically I would like to split out the array into separate strings so I can assign those values to separate edittext fields.
This is my current attempt in my main activity:
public void showNextRandomQuestion()
{
SQLDatabaseHelper db = new SQLDatabaseHelper(this);
StringTokenizer tokens = new StringTokenizer(db.getAllAnswersByQuestion1(), ",");
String first = tokens.nextToken();
String second = tokens.nextToken();
questionView.setText(first);
answerText1.setText(second);
}
However the code will not compile as it wants to either 'change the return type of 'getAllAnswersByQuestion1() to string' - or 'Remove argument to match StingTokenizer(String)'
Can't seem to get around this.
for(List l : db.getAllAnswersByQuestion1()){
for(String s : l){
StringTokenizer tokens = new StringTokenizer(s, ",");
String first = tokens.nextToken();
String second = tokens.nextToken();
questionView.setText(first);
answerText1.setText(second);
}
}
this update will make your code work at least
It looks like you have both the question and answer stored in the QDESCR field, comma delimited.
If that is the case, then something like the code below would work.
I assume that you want to select a random question from the list, given the method name.
You can use Random in order to generate a random index of the list.
You might want to add logic to prevent previously selected questions from coming up again.
Here is the basic code that gets the question/answer, and question ID:
public void showNextRandomQuestion() {
//get the data from the database
List<List<String>> listList = db.getAllAnswersByQuestion1();
//Get the question/answer Strings and the question IDs
List<String> questionStrings = listList.get(0); //question and answer Strings
List<String> questionIDs = listList.get(1); //question IDs
//Generate random index
Random r = new Random();
int rand = Math.abs((r.nextInt() % questionStrings.size()));
//get question ID for randomly selected question
String questionID = questionIDs.get(rand);
//Separate out the question/answer of randomly selected question
StringTokenizer tokens = new StringTokenizer(questionStrings.get(rand), ",");
String first = tokens.nextToken();
String second = tokens.nextToken();
questionView.setText(first);
answerText1.setText(second);
}
Also, note that it would be better to use String.split(), as is stated in the documentation.
Related
I have a table that contains some value and I am using a hash map to provide key value mapping:
|type|uri |client |
|----|----------------|-------|
| |https://test.com|test |
|aspx |test |
|aspx|https://test.com| |
What I would like to do is build a url based on the values provided. So basically below what I do is check if any values are not empty, to add them in an array list like so.
private static final String CLIENT = "client";
private static final String URI = "uri";
private static final String TYPE = "type";
public void GetAuthorizeMissingRequiredFields(final Table table) {
final String url = “/test/platform/auth”;
final List<TableRow> rows = table.getTableRows();
final Map<String, String> headers = getCurrentHeaders().getMap();
ArrayList<String> queryParamsList = new ArrayList<>();
rows.forEach(row -> {
final String clientValue = row.getCell("client");
final String uriValue = row.getCell("uri");
final String typeValue = row.getCell("type");
if (!clientValue.isEmpty()) {
queryParamsList.add(CLIENT + clientValue);
}
if (!uriValue.isEmpty()) {
queryParamsList.add(URI + uriValue);
}
if (!typeValue.isEmpty()) {
queryParamsList.add(TYPE + typeValue);
}
});
}
Now here is my question. As you can see above I have a url string. What I want to do is add each item from the array list as a query para. So based on the table, the url should look like so:
Scenario 1:
/test/platform/auth?uri=https://test.com&client=test
Scenario 2:
/test/platform/auth?type=aspx&client=test
Scenario 3:
/test/platform/auth?type=aspx&uri=https://test.com
My question is how to do this append of the list items into a string as query params.
Now, a problem I see is what you add to the list: you append e.g. CLIENT + clientValue (resulting in "clienttest"), but what would be better in my opinion would be CLIENT + "=" + clientValue(resulting in "client=test").
The second issue is that you append the content of all map rows to the ArrayList in that form. So your list can easily have multiple clients, URIs and types if there is more than one row in your table.
Now you either miss or ignore this in your examples on purpose. Since I do not know your exact goal, I can suggest you the following to append the content of the whole ArrayList in its current form:
url += "?" + String.join("&", queryParamsList);
or, alternatively,
url += "?" + queryParamsList.stream().collect(Collectors.joining("&"));
If you want to build a separate url String for each row, you will need a list of url Strings:
final String URL_CORE = “/test/platform/auth”;
List<String> urls = new ArrayList<>();
rows.forEach(row -> {
final String clientValue = row.getCell("client");
final String uriValue = row.getCell("uri");
final String typeValue = row.getCell("type");
urls.add(URL_CORE + "?" +
(clientValue.isEmpty ? "" : CLIENT + "=" + clientValue + "&") +
(uriValue.isEmpty ? "" : URI + "=" + uriValue + "&") +
(typeValue.isEmpty ? "" : TYPE + "=" + typeValue);
});
I need help to parse a string in Java... I'm very new to Java and am not sure how to go about it.
Suppose the string I want to parse is...
String str = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235;"
What I would want to do is:
String name = C43
String direction = EB2;
Then what I'd like to do is store 2 coordinates as a pair...
Coordinate c1 = 49.21716;-122.667252;
Coordinate c2 = 49.216757;-122.666235;
And then make a List to store c1 and c2.
So far I have this:
parseOnePattern(String str) {
String toParse = str;
name = toParse.substring(1, toParse.indexOf("-"));
direction = toParse.substring(toParse.indexOf("-", toParse.indexOf(";")));
I'm not sure how to move forward. Any help will be appreciated.
A simple substring function may solve your problem.
String str = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235;";
String[]s = str.split(";");
String[]n = s[0].split("-");
String name = n[0].substring(1);
String direction = n[1];
String c1 = s[1] +";"+s[2];
String c2 = s[3] +";"+s[4];
System.out.println(name + " " + direction);
System.out.println(c1 + " " + c2);
I hope this helps you.
Welcome to Java and the whole set of operations it allows to perform on Strings. You have a whole set of operations to perform, I will give you the code to perform some of them and get you started :-
public void breakString() {
String str = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235";
// Will break str to "NC43-EB2" and "49.21716" "-122.667252" "49.216757" "-122.666235"
String [] allValues = str.split(";", -1);
String [] nameValuePair = allValues[0].split("-");
// substring selects only the specified portion of string
String name = nameValuePair[0].substring(1, 4);
// Since "49.21716" is of type String, we may need it to parse it to data type double if we want to do operations like numeric operations
double c1 = 0d;
try {
c1 = Double.parseDouble(allValues[1]);
} catch (NumberFormatException e) {
// TODO: Take corrective measures or simply log the error
}
What I would suggest you is to go through the documentation of String class, learn more about operations like String splitting and converting one data type to another and use an IDE like Eclipse which has very helpful features. Also I haven't tested the code above, so use it as a reference and not as a template.
Ok i made this:
public static void main(String[] args) {
String str = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235;";
String[] strSplit = str.split(";");
String[] nameSplit=strSplit[0].split("-");
String name=nameSplit[0].replace("N", "");
String direction= nameSplit[1];
String cordanateOne = strSplit[1]+";"+strSplit[2]+";";
String cordanateTwo = strSplit[3]+";"+strSplit[4]+";";
System.out.println("Name: "+name);
System.out.println("Direction: "+direction);
System.out.println("Cordenate One: "+cordanateOne);
System.out.println("Cordenate Two: "+cordanateTwo);
}
Name: C43
Direction: EB2
Cordenate One: 49.21716;-122.667252;
Cordenate Two: 49.216757;-122.666235;
String str3 = "NC43-EB2;49.21716;-122.667252;49.216757;-122.666235;";
String sub = str3.substring(0,4); // sub = NC43
String sub4 = str3.substring(5,9); // sub = EB2;
HashMap<String, String> hm = new HashMap<>();
hm.put(str3.substring(9 ,30), str3.substring(30));
hm.forEach((lat, lot) -> {
System.out.println(lat + " - " + lot); // 49.21716;-122.667252; - 49.216757;-122.666235;
});
//edit if using an array non pairs (I assumed it was lat + lon)
List<String> coordList = new ArrayList<>();
coordList.add(str3.substring(9 ,30));
coordList.add(str3.substring(30));
coordList.forEach( coord -> {
System.out.println(coord);
});
//output : 49.21716;-122.667252;
49.216757;-122.666235;
I have a List of Strings containing names and surnames and i have a free text.
List<String> names; // contains: "jon", "snow", "arya", "stark", ...
String text = "jon snow and stark arya";
I have to find all the names and surnames, possibly with a Java Regex (so using Pattern and Matcher objects). So i want something like:
List<String> foundNames; // contains: "jon snow", "stark arya"
I have done this 2 possible ways but without using Regex, they are not static beacause part of a NameFinder class that have a list "names" that contains all the names.
public List<String> findNamePairs(String text) {
List<String> foundNamePairs = new ArrayList<String>();
List<String> names = this.names;
text = text.toLowerCase();
for (String name : names) {
String nameToSearch = name + " ";
int index = text.indexOf(nameToSearch);
if (index != -1) {
String textSubstring = text.substring(index + nameToSearch.length());
for (String nameInner : names) {
if (name != nameInner && textSubstring.startsWith(nameInner)) {
foundNamePairs.add(name + " " + nameInner);
}
}
}
}
removeDuplicateFromList(foundNamePairs);
return foundNamePairs;
}
or in a worse (very bad) way (creating all the possible pairs):
public List<String> findNamePairsInTextNotOpt(String text) {
List<String> foundNamePairs = new ArrayList<String>();
text = text.toLowerCase();
List<String> pairs = getNamePairs(this.names);
for (String name : pairs) {
if (text.contains(name)) {
foundNamePairs.add(name);
}
}
removeDuplicateFromList(foundNamePairs);
return foundNamePairs;
}
You can create a regex using the list of names and then use find to find the names. To ensure you don't have duplicates, you can check if the name is already in the list of found names. The code would look like this.
List<String> names = Arrays.asList("jon", "snow", "stark", "arya");
String text = "jon snow and Stark arya and again Jon Snow";
StringBuilder regexBuilder = new StringBuilder();
for (int i = 0; i < names.size(); i += 2) {
regexBuilder.append("(")
.append(names.get(i))
.append(" ")
.append(names.get(i + 1))
.append(")");
if (i != names.size() - 2) regexBuilder.append("|");
}
System.out.println(regexBuilder.toString());
Pattern compile = Pattern.compile(regexBuilder.toString(), Pattern.CASE_INSENSITIVE);
Matcher matcher = compile.matcher(text);
List<String> found = new ArrayList<>();
int start = 0;
while (matcher.find(start)) {
String match = matcher.group().toLowerCase();
if (!found.contains(match)) found.add(match);
start = matcher.end();
}
for (String s : found) System.out.println("found: " + s);
If you want to be case sensitive just remove the flag in Pattern.compile(). If all matches have the same capitalization you can omit the toLowerCase() in the while loop as well.
But make sure that the list contains a multiple of 2 as list elements (name and surname) as the for-loop will throw an IndexOutOfBoundsException otherwise. Also the order matters in my code. It will only find the name pairs in the order they occur in the list. If you want to have both orders, you can change the regex generation accordingly.
Edit: As it is unknown whether a name is a surname or name and which build a name/surname pair, the regex generation must be done differently.
StringBuilder regexBuilder = new StringBuilder("(");
for (int i = 0; i < names.size(); i++) {
regexBuilder.append("(")
.append(names.get(i))
.append(")");
if (i != names.size() - 1) regexBuilder.append("|");
}
regexBuilder.append(") ");
regexBuilder.append(regexBuilder);
regexBuilder.setLength(regexBuilder.length() - 1);
System.out.println(regexBuilder.toString());
This regex will match any of the given names followed by a space and then again any of the names.
I am developing an application in which I came across the requirement where I need to do the replacement of identifying words with the strings i.e. replacing the actual data in templates. In this I am getting the data from an arraylist and for that I have implemented the following solution.
List<String> abc = new ArrayList<String>();
abc.add("willy brown");
abc.add("jamster");
String message="//$^$// has commented on //$^$// .";
String messages[] = message.split(" ");
StringBuffer finalMessage = new StringBuffer();
for(int i=0,j=0; i<messages.length && j<=abc.size(); i++){
System.out.println("messages : " + messages[i]);
if(messages[i].equals("//$^$//")){
messages[i] = abc.get(j);
System.out.println("after changes " +messages[i]);
j++;
}
finalMessage.append(messages[i] +" ");
}
System.out.println("final message: " + finalMessage);
I just want to know if there is any better way to implement this and also if there is any vulnerability in this.
I would use MessageFormat.format for this:
List<String> abc = new ArrayList<String>();
abc.add("willy brown");
abc.add("jamster");
String message = "{0} has commented on {1}";
String finalMessage = MessageFormat.format(message, abc.toArray(new String[abc.size()]));
System.out.println(finalMessage);
You can use the built in String and StringBuffer methods to perform this task without having to break apart the message into an array. I also suggest extracting your field identifier into a separate variable. God forbid you miss-type it somewhere!
String fieldIdentifier = "//$^$//";
List<String> abc = new ArrayList<>();
abc.add("willy brown");
abc.add("jamster");
String message= fieldIdentifier + " has commented on " + fieldIdentifier + ".";
StringBuffer finalMessage = new StringBuffer(message);
int fieldCount = 0;
while(finalMessage.indexOf(fieldIdentifier) > -1) {
int index = finalMessage.indexOf(fieldIdentifier);
finalMessage = finalMessage.replace(index, index + fieldIdentifier.length(), abc.get(fieldCount));
fieldCount++;
}
System.out.println("final message: " + finalMessage);
Edit: using StringBuffer for these kinds of operations is highly preferable, since it is mutable and much faster than using String.
I have a array list of integers . I want to use this list in the IN clause of SQL query. I tried to do the below, but i know it wont work. Can someone suggest a better way .
List<Integer> **plcList** = new ArrayList<Integer>();
String finalQuery = "
select plc,direction,ROUND(AVG(CAST(speed as float)),2) as speed,COUNT(plc) as count,time_id
from processed
WHERE plc IN " + " " + "(**plcList**)"+ " " + "
group by plc, direction, time_id";
I suggest to have a look on this one: PreparedStatement IN clause alternatives?
And this page: http://www.javaranch.com/journal/200510/Journal200510.jsp#a2
In your case, you could just loop to build the integer list as Abdul mentioned above.
I am not a Java prof. but I would suggest you to loop throug your list and make string with comma seperated values. Like in PHP we do this with implode function. And hence your final string would be something like this
1,2,3,4,5
and then use it in your sql query
I am not sure about my code but try this as I am not a Java programmar (
make the necessary changes if any syntax error)
String intlist = "";
for (String temp : list)
{
intlist += ","+temp;
}
String Str = new String(intlist);
String sqlstring = Str.substring(1);
Try this..
List<Integer> myList = new ArrayList<Integer>();
StringBuilder builder = new StringBuilder();
// length of the list
int locSize = myList.size();
Object[] args = new Object[locSize];
for( int i = 0; i < locSize; i++ ) {
builder.append(" ?, " );
args[i]= myList.get(i);
}
You can then use this in your query, something like this.
....WHERE plc IN ("+ builder.toString() +") group by plc, direction, time_id";
Refer passing object[] to sql query for similar question.