How to compare String to all elements in an array? [duplicate] - java

This question already has answers here:
How do I determine whether an array contains a particular value in Java?
(30 answers)
Closed 7 years ago.
I am looking for a way to compare a string (which in this case will be a line from a text file) to every element in an array and see if there is a match. At a high level overview, I have a string array (about 100 elements) full of strings that are all contained somewhere in the file that need to be deleted. So I am reading a file into a StringBuffer and writing each line, except skipping over all lines that match an element in the array. This is what I have so far:
//Main Class calling the method
public class TestApp {
public static void main(String[] args) {
CompareAndDelete.RemoveDuplicateLines("C:/somelocation", 2Darray);
}
}
public class CompareAndDelete {
static string Line_of_Text;
static StringBuffer localBuff = new StringBuffer();
static FileReader Buffer;
static BufferedReader User_File;
public static void RemoveDuplicateLines(String local, String[][] duplicates) throws IOException
{
//Converting 2D array to one-dimensional array
final String[] finalDups = new String[duplicates.length];
for(int i = 0; i < duplicates.length; i++)
{
finalDups[i] = duplicates[i][0]+" "+duplicates[i][1];
}
int count = 0;
User_File = new BufferedReader(Buffer);
Set<String> Values = new HashSet<String>(Arrays.asList(finalDups));
while((Line_of_Text = User_File.readLine()) != null){
if(!(Values.contains(Line_of_Text))){
localBuff.append(Line_of_Text+"\n");
}else{
count++;
}
}
System.out.println(count);
//Printing StringBuffer to file
BufferedWriter testOutFile = new BufferedWriter(new FileWriter("C:/test.txt"));
testOutFile.write(localBuff.toString());
testOutFile.flush();
testOutFile.close();
}
So I am unsure of the IF statment, I know that it does not work properly, it currently is only removing the first few elements in the new StringBuffer because those lines happen to be towards the end of the file, and it does not recheck every line for a match with each element. I know there has to be a better way to do this... Thanks in advance for any help/suggestions.
**Updated: with code above, it is now throwing the following error on this line:
while((Line_of_Text = User_File.readLine()) != null){
Error:
Exception in thread "main" java.io.IOException: Stream closed
at sun.nio.cs.StreamDecoder.ensureOpen(StreamDecoder.java:51)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:204)
at java.io.InputStreamReader.read(InputStreamReader.java:188)
at java.io.BufferedReader.fill(BufferedReader.java:147)
at java.io.BufferedReader.readLine(BufferedReader.java:310)
at java.io.BufferedReader.readLine(BufferedReader.java:373)
at compare.CompareAndDelete.RemoveDuplicateLines(CompareAndDelete.java:48)
at mainPackage.TestApp.main(TestApp.java:326)

This can be accomplished quite efficiently by adding your String array members to a Set, and then checking whether the set contains() the current line. Example:
Set<String> ignoredStrings = new HashSet<String>(Arrays.asList(arr));
String line;
while ((line = file.readLine()) != null) {
if (!ignoredStrings.contains(line)) {
buffer.append(line);
buffer.append("\n");
}
}

Here is a method:
public boolean isStringInArray(String str, String[] strarr){
for(String s: strarr){
if(str.equals(s)) return true;
}
return false
}
isStringInArray("Hello", new String[]{"Hello", "World"}); // True
isStringInArray("Hello", new String[]{"hello", "World"}); // False

Related

Why am I getting the original word plus the reverse word?

My return for the input "no" is showing up as "noon"
I'm seeing where it is adding the original word to the StringBuilder. How do I get it to not do that, and only add the characters to an empty StringBuilder, in reverse?
public class Palindrome
{
public static String reversed(String originalWord)
{
int lengthOfWord = originalWord.length();
StringBuilder reversedWordBuilder = new StringBuilder(originalWord);
for (int currentChar = lengthOfWord-1; currentChar >= 0; currentChar--)
{
reversedWordBuilder.append(Character.toString(originalWord.charAt(currentChar)));
}
return reversedWordBuilder.toString();
}
}
You are initializing the StringBuilder with the originalWord itself:
StringBuilder reversedWordBuilder = new StringBuilder(originalWord);
so it already have initial a value of "no", then you append the reversed one to it. You should initialize it with empty constructor like:
StringBuilder reversedWordBuilder = new StringBuilder();
and then to do your logic in the loop.
Since you already use StringBuilder you can do in one liner as it follows:
public static String reversed(String originalWord) {
return new StringBuilder(originalWord).reverse().toString();
}

Getting null as an output from array

import java.util.*;
public class a{
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File ("master file.txt"));
String[] ids = new String[100];
System.out.println(ids);
while(sc.hasNext()) {
int i = 0;
ids[i] = sc.next();
i++;
}
I tried to put the data from a file to an array. Im always getting a null as an output. I cant figure out why. This has been very stressing.
You are printing an array before you filled it with elements.
Your counter i is reseting to 0 in every iteration of your while loop. Although it's not a good idea to use array with fixed number of elements for reading text of unknown length, so use some dynamic array like ArrayList.
Make sure you have provided the correct path to your .txt file.
So your code could look like this:
Scanner sc = new Scanner(new File ("C:/correct/path/to/file/master_file.txt"));
List<String> listOfStrings = new ArrayList<String>();
while(sc.hasNextLine()) {
listOfStrings.add(sc.nextLine());
}
System.out.println(listOfStrings);
The output is null because you never assigned anything the array before you try to print it. I also moved the i outside of the loop so it doesn't get reinitialized each time. Also since the ids is an array you need to use Arrays.toString(ids) to print it or you just get the object id.
public static void main(String[] args) throws FileNotFoundException {
String[] ids = new String[100]; //array to store lines
int i = 0; // line index
try (Scanner sc = new Scanner(new File ("master file.txt"))) { // try resource
while(sc.hasNextLine()) { // check for next line
ids[i] = sc.nextLine(); // store line to array index
i++; // increment index
}
}
System.out.println(Arrays.toString(ids)); //print output.
}

delete full arraylist element if it has specific sub string in code [duplicate]

This question already has answers here:
Properly removing an Integer from a List<Integer>
(8 answers)
Closed 5 years ago.
I have an ArrayList whose output is given as:
[, bd33b056-7a24-490f-a4bb-88cb2687facb%1514759804437%New York, USA%Florida, USA%2018-01-01%2018-01-10%UM-66%3050.0, bd33b056-7a24-490f-a4bb-88cb2687facb%1514759837907%New York, USA%California, USA%2018-01-01%2018-01-10%UM-66%8770.0]
Now I am creating a method to have a string id as parameter, when ever is matches with the id of booking it will remove that index.
The id is after first %, is there any way to find out index of that specific booking?
Here is method
public static void removeElement(String id) throws FileNotFoundException, IOException{
BufferedReader b = new BufferedReader(new FileReader("Booking.dat"));
String d = b.readLine();
String[] allB = d.split("£");
ArrayList<String> data = new ArrayList<String>(Arrays.asList(allB));
data.remove(id);// need to have specific index of id inside the full arraylist
System.out.println(data);
}
You can remove the elements that contain the specified id with removeIf:
data.removeIf(e -> e.contains(id));
if you want to remove elements where the id only has % at the beginning and at the end then you can do:
data.removeIf(e -> e.contains("%"+id+"%"));
I am not sure why you insist of having the index, because streams would be much more efficient, but this method gets the index as requested and removes that element:
public static void removeElement(String id) {
BufferedReader b = new BufferedReader(new FileReader("Booking.dat"));
String d = b.readLine();
String[] allB = d.split("£");
ArrayList<String> data = new ArrayList<String>(Arrays.asList(allB));
// Variable to save the index to. Set to -1 in case the index does not exist.
int index = -1;
for (int i = 0; i < data.size(); i++) { // Iterate through data
// Check if this index contains the id
if (data.get(i).contains(id)) {
index = i; // If it matches save the index and break
break;
}
}
if (index == -1) // If the index was never saved, return.
return;
data.remove(index);
System.out.println(data);
}

Hashmap get function returns null

I have a hashmap which is
public HashMap<String, ArrayList<Integer>> invertedList;
I show you my invertedList in watch list during debugging:
invertedList.toString(): "{ryerson=[0, 2, 3], 23=[3], award=[1], andisheh=[0, 2]}"
In the same watch list when I enter:
invertedList.get("ryerson")
I get null as result, also in the code. As you can see "ryerson" is already there as a key in my invertedList and I should get [0, 2, 3] as a result!!! What is happening here? I'm so confused!
I know there is a problem with ArrayList as values, because I tested Integer as values and it worked fine, but still don't know how to solve it. I am new to java, used to work with C#.
The complete code of invertedList:
public class InvertedIndex {
public HashMap<String, ArrayList<Integer>> invertedList;
public ArrayList<String> documents;
public InvertedIndex(){
invertedList = new HashMap<String, ArrayList<Integer>>();
documents = new ArrayList<String>();
}
public void buildFromTextFile(String fileName) throws IOException {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
int documentId = 0;
while(true){
String line = bufferedReader.readLine();
if(line == null){
break;
}
String[] words = line.split("\\W+");
for (String word : words) {
word = word.toLowerCase();
if(!invertedList.containsKey(word))
invertedList.put(word, new ArrayList<Integer>());
invertedList.get(word).add(documentId);
}
documents.add(line);
documentId++;
}
bufferedReader.close();
}
The test code:
#Test
public void testBuildFromTextFile() throws IOException {
InvertedIndex invertedIndex = new InvertedIndex();
invertedIndex.buildFromTextFile("input.tsv");
Assert.assertEquals("{ryerson=[0, 2, 3], 23=[3], award=[1], andisheh=[0, 2]}", invertedIndex.invertedList.toString());
ArrayList<Integer> resultIds = invertedList.get("ryerson");
ArrayList<Integer> expectedResult = new ArrayList<Integer>();
expectedResult.add(0);
expectedResult.add(2);
expectedResult.add(3);
Assert.assertEquals(expectedResult, resultIds);
}
The first Assert works fine, the second one, resultIds is null.
If I'm reading this right, and assuming correctly, this test function is inside the InvertedIndex class. I only make that assumption because the line
ArrayList<Integer> resultIds = invertedList.get("ryerson");
should actually be uncompilable as there is no local variable called "invertedList".
That line should read
ArrayList<Integer> resultIds = invertedIndex.invertedList.get("ryerson");
Your first assert tests the value of invertedIndex.invertedList. The second one gets a value from invertedList, and not from invertedIndex.invertedList. You've probably defined a map with the same name in your test, which is different from the one used by invertedIndex.

How to find all error messages and display them in descending order

Hi I am trying to sort input file from user for error messages in descending orders of occurrence.
input_file.txt
23545 debug code_to_debug
43535 error check your code
34243 error check values
32442 run program execute
24525 error check your code
I want to get output as
error check your code
error check values
My code currently:
import java.io.*;
import java.util.*;
public class Sort {
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new FileReader("fileToRead"));
Map<String, String> map=new TreeMap<String, String>();
String line="";
while((line=reader.readLine())!=null){
map.put(getField(line),line);
}
reader.close();
FileWriter writer = new FileWriter("fileToWrite");
for(String val : map.values()){
writer.write(val);
writer.write('\n');
}
writer.close();
}
private static String getField(String line) {
return line.split(" ")[0];//extract value you want to sort on
}
}
Change your mapping from <String, String> to <Integer, String>. Then, use a custom Comparator to compare the Integers from least to greatest.
It appears that your error messages are ranked by an integer value from most severe to least severe. This should allow you to use that fact.
Rather than having a Map<String,String> where the key is the integer value you could have the key as the error message and then the value could hold a list of the integer values so when reading the file it would become something like and also implement a comparator in the map to order them:
Map<String, String> map = new TreeMap<String, List<String>>(new Comparator<String>()
{
#Override
public int compare(String s1, String s2)
{
//Implement a compare to get the order of string you want
}
}
);
String line = "";
while((line = reader.readLine()) != null)
{
String lineStr = line.split(" ")[1]; // get the message
List<String> vals = map.get(lineStr) // get the existing list
if( vals == null)
vals = new ArrayList<String>(); // create a new list if there isn't one
vals.add(getFeild(line)); // add the int value to the list
map.put(lineStr,vals); // add to map
}
You could then sort the list into numeric order if you wanted. Also this would then require a bit more work to print out the map - but this depends on the format
If all you want to do is reorder the input so all the error messages appear at the top, a very simple way to do it is like the following:
static String[] errorsToTop(String[] input) {
String[] output = new String[input.length];
int i = 0;
for(String line : input) {
if(line.contains("error"))
output[i++] = line;
}
for(String line : input) {
if(!line.contains("error"))
output[i++] = line;
}
return output;
}
That just copies the array first starting with all errors messages, then will all non-error messages.
It's also possible to make those two loops a nested loop though the logic is less obvious.
static String[] errorsToTop(String[] input) {
String[] output = new String[input.length];
int i = 0;
boolean not = false;
do {
for(String line : input) {
if(line.contains("error") ^ not)
output[i++] = line;
}
} while(not = !not);
return output;
}
It's unclear to me whether the numbers appear in your input text file or not. If they don't, you can use startsWith instead of contains:
if(line.startsWith("error"))
You could also use matches with a regex like:
if(line.matches("^\\d+ error[\\s\\S]*"))
which says "starts with any integer followed by a space followed by error followed by anything or nothing".
Since no answer has been marked I'll add 2 cents.
This code below works for exactly what you posted (and maybe nothing else), it assumes that errors have higher numbers than non errors, and that you are grabbing top N of lines based on a time slice or something.
import java.util.NavigableMap;
import java.util.TreeMap;
public class SortDesc {
public static void main(String[] args) {
NavigableMap<Integer, String> descendingMap = new TreeMap<Integer, String>().descendingMap();
descendingMap.put(23545, "debug code_to_debug");
descendingMap.put(43535, "error check your code");
descendingMap.put(34243, "error check values");
descendingMap.put(32442, "run program execute");
descendingMap.put(24525, "error check your code");
System.out.println(descendingMap);
}
}
results look like this
{43535=error check your code, 34243=error check values, 32442=run program execute, 24525=error check your code, 23545=debug code_to_debug}

Categories

Resources