comparing 2 ArrayList in Java - java

I got 2 ArrayList
List fileArray = new ArrayList();
List fileTxt = new ArrayList();
List<String> newDoc = new ArrayList<String>();
while((fileName = fileRead.readLine()) !=null){
fileArray.add(fileName);
}
fileRead.close();
while((txtName = txtRead.readLine()) !=null){
fileTxt.add(txtName);
}
txtRead.close();
I want to compare fileArray data with fileTxt data, but don't know how to do that, because to I'm thinking to compare I need to get the data first. And to do that I need to looping the array and using the .get like
for(int a=0;a<fileTxt.size();a++){
System.out.println(fileTxt.get(a));
}
I know this is wrong, but anyone can help me.
note: I want to use something like contains method but can't because the data is 5 million rows. (not equals method)
Updated: I want to find a word in fileTxt that appeared in the fileArray. (so basically its like contains)

To compare 2 values in your 2 arraylists, you do this:
if(fileArray.get(index).equals(fileTxt.get(index)))

There is a wondefull function.
System.out.println(array1.equals(array2));
Then, you might want to check your answer by hands:
ArrayList like1 = new ArrayList();
ArrayList like2 = new ArrayList();
...
boolean flag = true;
if (!Math.min(like1.size(), like2.size()) == Math.max(like1.size(), like2.size()))
{
flag = false;
}
for (int i = 0; i < Math.min(like1.size(), like2.size()); i++) {
if (!like1.get(i).equals(like2.get(i))) {
flag = false;
break;
}
}

You can do this using the removeAll() method.
fileArray.removeAll(fileTxt);
fileTxt.removeAll(fileArray);
If one of them still have data, this means that the two List where different.
But storing 5 millions data in a Java list is not something I will advise you. Perhaps you should think about something else.

Related

how to check contains in arraylist or set

I have two Strings
String first = "value=[ABC,PQR,XYZ]"
String second="value=[ABC]"
I am trying to check the contains of string second into a string first.
I am using the below code
List<String> list = new Arraylist<>();
list.add(first);
if(list.contains(second)){
// do something
}
How to check contains in the list which has string with multiple ","?
Which data structure should I use for above problem?
Probably, you don't know how to work with lists in java...
In your case, you are adding a string "value=[ABC,PQR,XYZ]" to the list. Hence, you have a list with only one item.
If you want to create such a list ["ABC","PQR","XYZ"], you have to add these three elements one by one.
P.S. If you studied java basic, you wouldn't have such problems...
String first = "value=[ABC,PQR,XYZ]";
String second ="value=[ABC]";
String secondVal = second.substring(second.indexOf("[") + 1, second.indexOf("]"));
String[] firstArry = first.substring(first.indexOf("[") + 1, first.indexOf("]")).split(",");
boolean secondInFirst = false;
for (int i = 0; i < firstArry.length; i++) {
if (firstArry[i].equals(secondVal)) {
secondInFirst = true;
break;
}
}
I'm not sure why the first and second are formatted in such a way, however, assuming they are always formatted the same way ("value=[X,Y,Z]"),
We must break first up into a fixed list ("value=[ABC,PQR,XYZ]" -> {"ABC","PQR","XYZ"})
Format second to be readable ("value=[ABC]" -> "ABC")
Loop through firstArry and find matches
Store the result in secondInFirst

find if ArrayList contains atleat one different string

I have an Arraylist of Strings that may or may not contain duplicates,
list = ["car", "car", "car"] OR list = ["car", "car", "bike", "car"]
I want to know something like below,
if(list contains All same strings)
same = true
else if(list contains atleast one different element)
same = false
Please help me out in writing above condition.
Put all values in a Set and check if size is 1 or more.
List<String> list = Arrays.asList("car", "car", "bike", "car");
Set<String> unique = new HashSet<String>(list);
boolean same;
if (unique.size() > 1) {
same = false;
} else {
same = true;
}
System.out.println(same); // prints false
System.out.println(list); // prints [car, car, bike, car]
If you are using Java 8 then this is very simple:
same = list.stream().distinct().count() > 1
If you are not familiar with streams, you can interpret this statement as: create a stream of the items in the list, filter out any duplicates and then count the number of unique items left in the stream.
containsAll() can check the list for whether all passed parameter is present or not. It accepts Collection type parameter as argument so make one more list pass only one parameter in that list and pass this as parameter to containsAll(). Following is dummy workable code
public static void main(String[] args)
{
List<String> list = new ArrayList<String>();
list.add("Car");
list.add("Car");
list.add("Car");
List<String> paramlist = new ArrayList<String>();
paramlist.add("Car");
boolean same = false;
if(list.containsAll(paramlist)){
same = true;
}
else{
same = false;
}
}

Iterator seems to be losing data java

I've got a method that returns a list of hashmaps (the data comes from a ResultSet).
While trying to use an iterator to loop through the data and convert it to a String array, I was finding that the code was not working - It seemed to be losing half of my array data while doing the loop.
When swapping it to use a for loop rather than an iterator, the data was not lost. I tried using both an Iterator() and ListIterator() to no avail
Here is my original code (that wasn't working):
public String[][] getLayoutEdges() throws SQLException {
ArrayList<String[]> returnArray = new ArrayList<>();
List<HashMap> layoutEdges = db.getLayoutEdgesFromDatabase();
ListIterator<HashMap> edgesIterator = layoutEdges.listIterator();
while(edgesIterator.hasNext()) {
ArrayList<String> tmpList = new ArrayList<>();
tmpList.add(edgesIterator.next().get("fromnode").toString());
tmpList.add(edgesIterator.next().get("tonode").toString());
tmpList.add(edgesIterator.next().get("distance").toString());
String[] tmpStr = new String[tmpList.size()];
returnArray.add(tmpList.toArray(tmpStr));
}
String[][] rtn = new String[returnArray.size()][returnArray.size()];
return returnArray.toArray(rtn);
}
Here is the code that does work:
public String[][] getLayoutEdges() throws SQLException {
ArrayList<String[]> returnArray = new ArrayList<>();
List<HashMap> layoutEdges = db.getLayoutEdgesFromDatabase();
for(HashMap tmp : layoutEdges) {
ArrayList<String> tmpList = new ArrayList<>();
tmpList.add(tmp.get("fromnode").toString());
tmpList.add(tmp.get("tonode").toString());
tmpList.add(tmp.get("distance").toString());
String[] tmpStr = new String[tmpList.size()];
returnArray.add(tmpList.toArray(tmpStr));
}
String[][] rtn = new String[returnArray.size()][returnArray.size()];
return returnArray.toArray(rtn);
}
Can anybody tell me why the iterator wasn't working? I'm okay with using a for loop, i just can't for the life of me work out why the original iterator code I wrote wasn't keeping all my data. Wondering if there's a step i'm missing or whether I was trying to use the wrong solution.
You're calling edgesIterator.next() three times for each iteration of the loop in your first snippet, which I'm pretty sure you don't want to do. Just don't do that:
while (edgesIterator.hasNext()) {
HashMap tmp = edgesIterator.next();
tmpList.add(tmp.get("fromnode").toString());
tmpList.add(tmp.get("tonode").toString());
tmpList.add(tmp.get("distance").toString());
String[] tmpStr = new String[tmpList.size()];
returnArray.add(tmpList.toArray(tmpStr));
}
As an aside, if you could avoid using raw types in your API, it would generally be cleaner - I'm talking about the use of HashMap here.
I would also generally favour the second version of your code anyway - unless you need to use the iterator explicitly for some reason, let the syntactic sugar of the enhanced for loop do it for you automatically.
Because of these lines :
tmpList.add(edgesIterator.next().get("fromnode").toString());
tmpList.add(edgesIterator.next().get("tonode").toString());
tmpList.add(edgesIterator.next().get("distance").toString());
The moment you are calling edgesIterator.next() its moving the cursor to the next element.

Naming Arraylists in a loop - Java

I need to create an Arraylist in a while loop with a name based on variables also in the loop. Here's what I have:
while(myScanner.hasNextInt()){
int truster = myScanner.nextInt();
int trustee = myScanner.nextInt();
int i = 1;
String j = Integer.toString(i);
String listname = truster + j;
if(listname.isEmpty()) {
ArrayList listname = new ArrayList();
} else {}
listname.add(truster);
i++;
}
The variable truster will show up more than once while being scanned, so the if statement is attempting to check if the arraylist already exists. I think I might have done that out of order, though.
Thanks for your help!
Store the ArrayLists in a Map:
Map<String, List<String> listMap = new HashMap<String,List<String>>();
while (myScanner.hasNextInt()){
// Stuff
List<String> list = new ArrayList<String>();
list.add(truster);
listMap.put(listname, list);
}
Note the use of generics (the bits in <>) to define the type of Object the List and Map can contain.
You can access the values stored in the Map using listMap.get(listname);
If I understand you correctly, create a list of lists or, better yet, create a map in which the key is the dynamic name you want and the value is the newly created list. Wrap this in another method and call it like createNewList("name").
Really not sure what you mean at all but you have some serious fundamental flaws with your code so I'll address those.
//We can define variables outside a while loop
//and use those inside the loop so lets do that
Map trusterMap = new HashMap<String,ArrayList<String>>();
//i is not a "good" variable name,
//since it doesn't explain it's purpose
Int count = 0;
while(myScanner.hasNextInt()) {
//Get the truster and trustee
Int truster = myScanner.nextInt();
Int trustee = myScanner.nextInt();
//Originally you had:
// String listname = truster + i;
//I assume you meant something else here
//since the listname variable is already used
//Add the truster concated with the count to the array
//Note: when using + if the left element is a string
//then the right element will get autoboxed to a string
//Having read your comments using a HashMap is the best way to do this.
ArrayList<String> listname = new ArrayList<String>();
listname.add(truster);
trusterMap.put(truster + count, listname);
i++;
}
Further, you are storing in myScanner a stream of Ints that will get fed in to the array, but which each have very different meanings (truster and trustee). Are you trying to read these in from a file, or user input? There are better ways of handling this and if you comment below with what you mean I'll update with a suggested solution.

Random accessing array, how to skip duplicates?

I have an XML array that I access to pull a random question from. How would I go about making sure there is no duplicates pulled? My current code follows.
private void getQuestion() {
// TODO Auto-generated method stub
res = getResources();
qString = res.getStringArray(R.array.questions);
rQuestion = qString[rgenerator.nextInt(qString.length)];
tokens = new StringTokenizer(rQuestion, ":");
wordCount = tokens.countTokens();
sep = new String[wordCount];
wArray = 0;
while (tokens.hasMoreTokens()) {
sep[wArray] = tokens.nextToken();
wArray++;
}
}
Any help would be appreciated.
The Fisher-Yates shuffle is an algorithm that is more or less designed for this purpose.
You are better off putting that array of questions in a list and use Collections.shuffle(). After that, simply iterate through the list. More information can be found at this related answer.
This solution will cost some memory for duplicating the list, but remember that the strings themselves won't be copied, only the references to the questions are. For maximum performance, use a list with random access (ArrayList), or use that as a replacement for the array. If you don't theshuffle method will create one internally.
If you want a fast way of getting only unique values from an array this link has a very fast method. Below uses an ArrayList, but it will not be hard for you to convert from string array to an ArrayList - or just use ArrayLists instead.
e.g. new ArrayList(Arrays.asList(myArray));
In short you use a hashset to only get unique values using this method
public static ArrayList GetUniqueValues(Collection values)
{
return new ArrayList(new HashSet(values));
}
Then use it like so
ArrayList x = new ArrayList();
x.add("abc");
x.add("abc");
x.add("abc");
x.add("def");
x.add("def");
x.add("ghi");
for (Object y : GetUniqueValues(x))
Log.d("something", y); //ok lets print the value
To yield the result of "abc, def, and ghi"
To be clear I agree with Travis to ask why you have duplicates. The above is to answer the question.
I figured it out. I switched it to
private void getQuestion() {
res = getResources();
qString = res.getStringArray(R.array.questions);
arrayLength = qString.length;
qTotal = arrayLength;
}
private void getRandom() {
rnd = rgenerator.nextInt(arrayLength);
rQuestion = qString[rnd];
qString[rnd] = "used";
seperate();
}
private void seperate() {
if (rQuestion != "used") {
tokens = new StringTokenizer(rQuestion, ":");
wordCount = tokens.countTokens();
sep = new String[wordCount];
wArray = 0;
while (tokens.hasMoreTokens()) {
sep[wArray] = tokens.nextToken();
wArray++;
}
qNumber++;
} else {
if (qNumber < qTotal) {
getRandom();
} else {
startActivity(new Intent("com.example.END"));
}
}
}
It gets the array from resources, then pulls a random question from the array. It then sets that one to "used" and splits it. It also checks to see if the pulled question is "used, and if it is, it pulls another question. It also goes to the end game activity if all questions are "used"

Categories