Storing objects in ArrayList instead of Array - java

I currently have a program that stores objects in an array that I need to store in an ArrayList instead.
This is how the objects were originally stored.
private String phrase = "Once upon a time";
private Letter[] letter_array = new Letter[16];
for (int i = 0; i < phrase.length(); i++) {
letter_array[i] = new Letter(phrase.charAt(i));
}
So now, I'm trying to use something like this instead.
private String phrase = "Once upon a time";
ArrayList<Letter> aToZ = new ArrayList<Letter>();
for (int i = 0; i < phrase.length(); i++) {
Letter x = new Letter.charAt(i);
aToZ.add(x);
}
Some of the code has been omitted, but these are the pertinent parts.
This doesn't work and I've tried variations, but I just really don't know how to do this.

Instead of
Letter x = new Letter.charAt(i);
you need
Letter x = new Letter(phrase.charAt(i));
in your 2nd code snippet

Letter x = new Letter(phrase.charAt(i));
You almost had it! You need to include the "phrase." before charAt, but everything else seems to be correct.
Try to think of the object > string > charAt sequence carefully when you reread your code. Ask yourself when you read over your code: "what is it exactly about the object that I want to reference/change?"

Related

Attempting to print Strings on seperate lines

While writing a project for a non CS class I ran into a problem. The project i had in mind is a type of quiz, wherein the user is asked a question and is given multiple choices for answers. Now, I intended to type these questions into a .txt file and use a file scanner to read them in, and create an array of questions like so:
public static String[] questionToString(Scanner sf) {
String temp = "";
String[] questions = new String[Q];
int i = 0;
while(sf.hasNext()){
for(int y = 0; y < 5; y++) {
temp += sf.nextLine();
}
questions[i] = temp;
i++;
temp = "";
return questions;
}
However, this code when tested would return something along the lines of:
Question 1 abcd
as opposed to:
Question 1
a
b
c
d
I want each character to be placed on it's own line, like in the second example. How can I do this while printing the strings? (System.out.println())
Eventually, I plan to put them on a DrawingPanel with the questions lined up below.
Thanks!
Use "\n" to add an extra line in addition to the line println() already appends:
System.out.println(your_var + "\n")
That is because you are adding questions lines to a string. So make a small change to the following line:
temp += sf.nextLine() + "\n";
Of course, the newline char depends on which environment you are running (\n or \r\n).
Best way to append many strings into one with a new line character after each one is to use StringBuilder. I have rewritten your code using StringBuilder
public static String[] questionToString(Scanner sf) {
StringBuilder temp = new StringBuilder();
String[] questions = new String[Q];
int i = 0;
while(sf.hasNext()){
for(int y = 0; y < 5; y++) {
temp.append(sf.nextLine());
temp.append(System.lineSeparator());
}
questions[i] = temp.toString();
i++;
temp = new StringBuilder();
return questions;
}
NOTE: Please don't append /n with your string as the new line character differs for different operating system. I will advise you to use System.lineSeparator(), this will append the new line character depending on the operating system you are running you code on.

Comparing arrays

I have String Array of a good couple hundred lines of code. I have two other String Arrays, one with values I want to replace, and the other with the value I want it to replace to. I need to go through each line of the original code and check each line if it contains anything that I need to replace, and if it does, replace it. I want to replace it to a totally different String Array, so that the original is still left unchanged. This is what I have, but it's not exactly working.
for(int i=0; i<originalCode.length; i++) {
if( originalCode[i].contains("| "+listOfThingsToReplace[i]) ) {
newCode[i]=originalCode[i].replaceAll(("| "+listOfThingsToReplace[i]), ("| "+listOfReplacingThings[i]));
}
}
Obviously I need more counting variables somewhere (especially because originalCode.length !=listOfThingsToReplace.length), but I can't figure out where. Would I need more for loops? I tired doing that... but "Exception in thread "main" java.lang.OutOfMemoryError: Java heap space"... Any help please?
I think this should do the trick if I'm understanding the problem correctly
// New Code Array
String[] newCode = new String[originalCode.length];
for (int i=0; i<originalCode.length; i++) {
// New Code Line
String newCodeLine = originalCode[i];
// Iterate through all words that need to be replaced
for (int j=0; j<listOfThingsToReplace.length; j++) {
// String to replace
String strToReplace = listOfThingsToReplace[j];
// String to replace with
String strToReplaceWith = (j >= listOfReplacingThings.length) ? "" : listOfReplacingStrings[j];
// If there is a string to replace with
if (strToReplaceWith != "") {
// then replace all instances of that string
newCodeLine = newCodeLine.replaceAll(strToReplace, strToReplaceWith);
}
}
// Assign the new code line to our new code array
newCode[i] = newCodeLine;
}

Can You Put Java Retval Into an Array

I'm scanning through an array of String objects, each string object is going to be broken down into a regex.
When going through a an enhanced for-loop I'm wondering, is it possible to put the retval into an array?
For example if I have String regex = new String[3];
Where regex[0] = "EVEN_BIN_NUM (0|1)*0"
The enhanced for-loop can break my String object up into EVEN_BIN_NUM and (0|1)*0
I want to be able to put EVEN_BIN_NUM in one array, and (0|1)*0 in another array. Here is the code I have that scans through the String array with the string objects
/*
* Run through each String object and appropriately place them in the kind,
* and explicit.
*/
for (int j = 0; j < regex.length; j++)
{
for (String retval: regex[j].split(" ", 2))
{
System.out.println(retval);
}
}
For regex[0].split(" ", 2) I get EVEN_BIN_NUM and (0|1)*0 returned separately.
Alternatively, if you know how to break this up in a better way, let me know:
EVEN_BIN_NUM (0|1)*0
ODD_BIN_NUM (0|1)*1
PET (cat|dog)
The parts in capital letters are to be put in the "kind" array, and the rest is to be put in another array.
So the kind array would have three strings, and the other array would have three strings.
Hopefully this isn't too confusing....
It might be a good idea to use a Map object to store your information, however, if you wanted to return your analysis as an array, you could return an array of arrays and do the following.
String[] regex = {"EVEN_BIN_NUM (0|1)*0", "ODD_BIN_NUM (0|1)*1", "PET (cat|dog)"} ;
String[][] split = new String[regex.length][];
for(int i = 0; i < regex.length; i++) {
split[i] = regex[i].split(" ", 2);
}
You can then access the data as follows
String firstProperty = split[0][0]; //EVEN_BIN_NUM
String firstRegex = split[0][1]; //(0|1)*0
String secondProperty = split[1][0]; //ODD_BIN_NUM
String secondRegex = split[1][1]; //(0|1)*1
etcetera.
Or using a map:
Map<String, Pattern> map = new HashMap<>();
for(int i = 0; i < regex.length; i++) {
String[] splitLine = regex[i].split(" ", 2);
map.put(splitLine[0], Pattern.compile(splitLine[1]));
}
This way your properties would map straight to your Patterns.
For example:
Pattern petPattern = map.get("PET");

Removing duplicate chars from a string passed as a parameter

I am a little confused how to approach this problem. The userKeyword is passed as a parameter from a previous section of the code. My task is to remove any duplicate chars from the inputted keyword(whatever it is). We have just finished while loops in class so some hints regarding these would be appreciated.
private String removeDuplicates(String userKeyword){
String first = userKeyword;
int i = 0;
while(i < first.length())
{
if (second.indexOf(first.charAt(i)) > -1){
}
i++;
return "";
Here's an update of what I have tried so far - sorry about that.
This is the perfect place to use java.util.Set, a construct which is designed to hold unique elements. By trying to add each word to a set, you can check if you've seen it before, like so:
static String removeDuplicates(final String str)
{
final Set<String> uniqueWords = new HashSet<>();
final String[] words = str.split(" ");
final StringBuilder newSentence = new StringBuilder();
for(int i = 0; i < words.length; i++)
{
if(uniqueWords.add(words[i]))
{
//Word is unique
newSentence.append(words[i]);
if((i + 1) < words.length)
{
//Add the space back in
newSentence.append(" ");
}
}
}
return newSentence.toString();
}
public static void main(String[] args)
{
final String str = "Words words words I love words words WORDS!";
System.out.println(removeDuplicates(str)); //Words words I love WORDS!
}
Have a look at this answer.
You might not understand this, but it does the job (it cleverly uses a HashSet that doesn't allow duplicate values).
I think your teacher might be looking for a solution using loops however - take a look at William Morisson's answer for this.
Good luck!
For future reference, StackOverflow normally requires you to post what you have, and ask for suggestions for improvement.
As its not an active day, and I am bored I've done this for you. This code is pretty efficient and makes use of no advanced data structures. I did this so you could more easily understand it.
Please do try to understand what I'm doing. Learning is what StackOverflow is for.
I've added comments in the code to assist you in learning.
private String removeDuplicates(String keyword){
//stores whether a character has been encountered before
//a hashset would likely use less memory.
boolean[] usedValues = new boolean[Character.MAX_VALUE];
//Look into using a StringBuilder. Using += operator with strings
//is potentially wasteful.
String output = "";
//looping over every character in the keyword...
for(int i=0; i<keyword.length(); i++){
char charAt = keyword.charAt(i);
//characters are just numbers. if the value in usedValues array
//is true for this char's number, we've seen this char.
boolean shouldRemove = usedValues[charAt];
if(!shouldRemove){
output += charAt;
//now this character has been used in output. Mark that in
//usedValues array
usedValues[charAt] = true;
}
}
return output;
}
Example:
//output will be the alphabet.
System.out.println(removeDuplicates(
"aaaabcdefghijklmnopqrssssssstuvwxyyyyxyyyz"));

Instruction assigns a value, but the value is not read or used in any subsequent instruction

I have a piece of code
for(int i = 0; i < num_of_random; i++){
String str = in.readLine();
if(str != null){
String[] randoms = new String[4];
randoms = str.split(",");
dateRanges[i] = Integer.parseInt(randoms[0]);
id[i] = Integer.parseInt(randoms[1]);
flag[i] = Integer.parseInt(randoms[2]);
system[i] = Integer.parseInt(randoms[3]);
}
}
When I run this code against findBugs, I get a suggestion for
"String[] randoms = new String[4];"
This instruction assigns a value to a local variable, but the value is not read or used in any subsequent instruction. Often, this indicates an error, because the value computed is never used.
Why do I get this?
Thanks a lot
Because you initialize a variable to a value (new String[4]), and then replace the variable value with another one (the result of str.split(",")) just after. The initialization is thus not necessary.
Your code is functionally equivalent to
String[] randoms = str.split(",");
except it allocates a new String array which is immediately discarded.
Because you can simply do this:
String[] randoms = str.split(",");
Try directly:
String[] randoms = str.split(",");
You don't need to instanciate a String[], the split method already does it.
This is an example of the technique that I call The I'm dumb technique.
Typically it is the result of a programmer writing code, but not understanding what they are doing. At some point the programmer read or heard something like this: "you must initialize all local variables!". When they wrote the code String[] randoms that popped into their head so they added = new String[4].
A more seasoned programmer might look at that and think I used to be dumb, but not any more! Lets move the variable declarations out of the loop and produce something like this:
String str;
String[] randoms;
for(int index = 0; index < num_of_random; ++index)
{
str = in.readLine();
if (str != null)
{
randoms = str.split(",");
dateRanges[index] = Integer.parseInt(randoms[0]);
id[index] = Integer.parseInt(randoms[1]);
flag[index] = Integer.parseInt(randoms[2]);
system[index] = Integer.parseInt(randoms[3]);
}
}

Categories

Resources