How to compare names in an arraylist using java - java

My brain in kind of sore and I can't put a finger on why this wouldn't work.
I have two arraylist
private ArrayList<String> name = new ArrayList<String>();
private ArrayList<String> name2 = new ArrayList<String>();
I need to check if the value in 'name' contains the value in 'name2' and if it is, iterate, here is my current code for this:
private ArrayList<Integer> getForeignKey() {
ArrayList<Integer> foreignKey = new ArrayList<Integer>();
for (int i = 0; i < name.size(); i++) {
int intForeignKey = 1;
for (int x = 0; x < name2.size(); x++)
//System.out.println(name.get(i) + " ---------------- " + name2.get(x));
if (!name.get(i).contains(name2.get(x)))
intForeignKey++;
else
break;
foreignKey.add(intForeignKey);
}
return foreignKey;
}
When this is printed out it will work fine for a couple of values, then it starts skipping numbers, so the output would be:
0
1
2
3
4
5
5
10
when it's suppose to be
0 1 3 4 5 5 6 7 8 8 8 9 10
What am I doing wrong? If more clarification is needed, I will try my best.
EDIT:
Please note that the numbers above are just example number of what the output should look like.
name contains:
a,b,c,d,e,f,g
name2 contains
a,b,c,c,d,e,e,f,g,g
name(index i) checks if it contains the name2(index x) value, if it contains the value do NOT increment the foreign key integer, if it does not contain the value then increment the foreign key integer.

Are you trying to find the names which are the same in both collections?
private final Set<String> names = new LinkedHashSet<String>();
private final Set<String> names2 = new LinkedHashSet<String>();
public Set<String> namesInBoth() {
Set<String> ret = new LinkedHashSet<String>(names);
ret.retainAll(names2);
return ret;
}

I'm not sure why this isn't working (what's in name and name2?). A much better way to do this, though, is to use a HashSet to store the unique names and then extract them into an ArrayList.

Possible error - you use .contains to compare Strings. You should use .equals or .equalsIgnoreCase instead.
EDIT:
private ArrayList<Integer> getForeignKey() {
ArrayList<Integer> foreignKey = new ArrayList<Integer>();
for (int i = 0; i < name.size(); i++) {
boolean found = false;
for (int x = 0; x < name2.size(); x++){
if (name.get(i).equals(name2.get(x))){
found = true;
break;
}
}
if(!found){
foreignKey.add(i);
}
}
return foreignKey;
}

Related

How to retrivew elements of an Array of unkown size in android studio

I have created an app which will find the common factors of 2 or more numbers entered by the user. I have used a single Edit Text field to get user input. Different numbers are separated by comma (,). All the numbers are stored in an array.
My question is that how can I access the elements of the array of n size. Following is the code. I want to find the factors of all the user entered numbers. I can find the the factors of integernumbers[0] index but after that the code thorws ArrayIndexOutOfBoundsException.
int factors1 = 0;
int factors12 = 0;
StringBuilder sb = new StringBuilder();
String value = edtCommonFact.getText().toString()
String[] stringsNumber = value.split(",");
Integer[] integersNumbers = new Integer[stringsNumber.length];
for (int i = 0; i<stringsNumber.length; i++){
integersNumbers[i] = Integer.parseInt(stringsNumber[i]);
}
Arrays.sort(integersNumbers);
for (int i = 1; i<=integersNumbers[0]; i++){
if (integersNumbers[0]%i == 0){
factors1 = i;
sb.append(factors1).append(" ");
for (int j = 1; j<=integersNumbers.length; j++){
if (integersNumbers[j]%j == 0){
factors12 = j;
sb.append(factors12).append(" ");
}
}
}
}
String result = sb.toString();
commonFactResult.setText("Common factors are: " + result);
Thanks in Advance
You can use ArrayList because not like an array it doesn't need a size declaration. As an example if we wants an String array with size 10 we need to declare it as
String[] s = new String[10]
but in ArrayLists you can define the ArrayList and use it for any no of items.
List<String> s = new ArrayList<>()

How to check if a number is between a range

I have a problem for an online course I am doing. The question is:
Given an Integer x, write a program which generates random numbers between x and 0 until each number in this range has been generated at least once. Once all numbers in this range have been generated, the program should display the numbers which were generated.
I have written a program which I thought would solve this but am having problems with the checking if a number is in the range. Here is my code so far:
public static void main(String[] args) {
Random generator = new Random();
ArrayList<Integer> range = new ArrayList<Integer>();
ArrayList<Integer> generated = new ArrayList<Integer>();
int x = 10;
int count = 0;
for(int i = 0; i<x+1; i++){
range.add(i);
}
while(range.isEmpty() != true){
int temp = generator.nextInt(x-1);
count++;
generated.add(temp);
if(range.contains(temp)){
range.remove(temp);
}
}
}
}
My idea was to first create two arraylists. The first would hold all numbers between 0 and the given x. The second would contain the random numbers generated. I then fill the range arraylist with the range between 0 and x. My While loop then checks this range list to see if it is empty. If not, it generates a random number, adds it to my second arraylist. I then check if this number is in the range arraylist - if it is it removes it and carries on. The problem I am having is it is running into IndexOutOfBoundsException after a few goes. I think this is because I am removing the generated numbers from the arraylist. Can anyone help me with fixing this
EDIT: I cant use any collections or other APIs. This part of the course is mainly about using Arrays and loops etc, not advanced Java stuff.
remove is an overloaded method, there is remove(int) which removes the item at the index specified and there is remove(T) which removes the first object int the list that is equal to the argument you passed in
since you passed an int to the method not an Integer, the first method is chosen
the simpliest modification to your code is replacing range.remove(temp); with range.remove(range.indexOf(temp)); or range.remove((Integer)temp)
also you have to call generator.nextInt(x+1); or else the program will be stuck in an infinite loop
You can just replace range.remove(temp); with range.removeIf(t -> t == temp);
Random generator = new Random();
ArrayList<Integer> range = new ArrayList<Integer>();
ArrayList<Integer> generated = new ArrayList<Integer>();
int x = 10;
int count = 0;
for(int i = 0; i<x+1; i++){
range.add(i);
}
while(range.isEmpty() != true){
int temp = generator.nextInt(x-1);
count++;
generated.add(temp);
if(range.contains(temp)){
range.removeIf(t -> t == temp);
}
}
OR You can use Iterator to remove from the List
for (Iterator<Integer> it = range.iterator(); it.hasNext(); ) {
Integer obj= it.next();
if (obj == temp) {
// Remove the current element from the iterator and the list.
it.remove();
break;
}
}
One more issue in your logic
int temp = generator.nextInt(x-1); The random number you are generating doesn't contain all the numbers. It should be int temp = generator.nextInt(x+2);
Hope the below will meet your requirement.
Random random = new Random();
int x = 3;
List<Integer> range = new ArrayList<>();
for(int i = 0; i <x+1; i++) {
range.add(i);
}
List<Integer> list = new ArrayList<>();
while (!list.containsAll(range)) {
list.add(random.nextInt(x + 1));
}
System.out.println(list);

Enumerate the unordered pairs (2-combinations) of a set

I'd like to iterate through an ArrayList representing a set of Persons and compare the content of each Person with each other Person. The content are full of Hasmaps in this form. I need to compare the Value of the matching Key (Key is unique) and get the difference of the Integer. This should iterate through all the Hashmaps and for all the Persons in the Arraylist. But I shouldn't compare p.e. Person A with Person C and then Person C again with Person A.
How can I code it?
I'm struggling for the last 3 hours.
public Integer comparison(){
ArrayList<HashMap> personList = new ArrayList<>();
for(int i = 0; i < personList.size(); i++){
HashMap<String, Integer> persons = new HashMap<>();
for(int j = i+1; j<persons.size(); j++){
// sum up the differences
}
difference+=difference;
}
return difference;
}
This topic in mathematics uses what are called Combinations wherein you need to find the set of all k-combinations of a set (persons A, B, and C). In this case it is simple to get all the combinations, because you know it is always only required to choose two elements; that is, k=2. See my outer loop and inner loop below for an easy way of achieving this:
for(int a=0; a < personList.size()-1 /* stop before last */; a++) {
for(int b=a+1 /* start after first */; b < personList.size(); b++) {
int sumDiff = 0;
System.out.print("person"+(char)('A'+a)+" compared with person"+(char)('A'+b)+" = ");
Set<String> keys = personList.get(a).keySet();
keys.retainAll(personList.get(b).keySet()); // keys in both only
for(String key : keys) {
sumDiff += Math.abs(personList.get(a).get(key)-personList.get(b).get(key));
}
System.out.println(sumDiff);
}
}
Output:
personA compared with personB = 11
personA compared with personC = 8
personB compared with personC = 9
First of all, it is very unclear as to what you want to do. I am assuming that you have been given the personList and you pass it to the function you are writing. If you want the result as a list of individual comments you need to add them to a list and return a List instead of an Integer.
The following code for your example should return a List which contains the values {11,8,9}. If you want the sum of these values like 11+8+9 then instead of adding each difference to a list add it to a variable initialized to 0 and declared outside the 1st for loop.
public List<Integer> comparison(ArrayList<HashMap> personList){
List<Integer> result = new ArrayList<Integer>();
//int res = 0;
for(int i = 0; i < personList.size(); i++){
for(int j=i+1; j< personList.size(); j++){
int difference = 0
for(Map.Entry<String, Object> entry : personList.get(i).entrySet()){
String key = entry.getKey();
int val = entry.getValue();
difference += Math.abs(personList.get(j).get(key) - val);
}
}
//res += difference
result.add(difference);
}
//return res;
return result;
}

How to break an ArrayList into groups?

I am trying to implement this method:
public ArrayList<ArrayList> groupWords(ArrayList<String> scrambledWords, int groupNumber);
The method takes an ArrayList of Strings and a number that represents the number of words in each group as parameters and then returns an ArrayList made of ArrayLists that contain groups of words according to the groupNumber parameter. For example, there is an ArrayList of 20 strings and I want to group that ArrayList into groups of 5 so I call the method like this:
ArrayList<ArrayList> groupedWords = groupWords(ArrayList, 5);
I am pretty sure that I need to have a for loop with another for loop nested inside, but I am not sure how to implement it.
How do I implement this method?
With Guava:
List<List<String>> groupedWords = Lists.partition(words, 5);
Something like this should work:
ArrayList<ArrayList<String>> grouped = new ArrayList<>();
for(int i = 0; i < words.size(); i++) {
int index = i/groupSize;
if(grouped.size()-1 < index)
grouped.add(new ArrayList<>());
grouped.get(index).add(words.get(i));
}
I haven't tested this code but basically I'm using the fact that integer division is always rounding to the next lowest Integer.
Example: 4/5=0.8 and is rounded to 0.
public ArrayList<ArrayList> groupWords(ArrayList<String> scrambledWords, int groupNumber){
int arraySize = scrambledWords.size();
int count = 0;
ArrayList<ArrayList> result = new ArrayList<>();
ArrayList<String> subResult = new ArrayList<>();
for(int i = 0 ; i < arraySize; i++){
if(count == groupNumber){
count = 0;
result.add(subResult);
subResult = new ArrayList<>();
}
subResult.add(scrambledWords.get(i));
count++;
}
return result;
}
This is simple Java Collections Soultion.
Suggestion : As a return type you should use ArrayList<ArrayList<String>>, and this should be the type for result also.

ArrayList and Loop

ArrayList<String> gradeN = new ArrayList<String>();
gradeN.add("one");
gradeN.add("two");
int num2 = 0;
while (num<5){
gradeN.get(0).concat("*");
num2++;
}
System.out.println(gradeN.get(0));
This is not working.
I want output like this:
one*****
and do this in a loop..
There are 2 mistakes in your code:
The variable incremented in your while loop is different to the one used in the condition.
Strings are immutable. String.concat returns a different String object and does not modify the original String. That means the value in your List is not modified. To fix this, use List.set to replace the old value in the list with a new one.
int num2 = 0;
while (num2 < 5) {
String newValue = gradeN.get(0).concat("*");
gradeN.set(0, newValue);
num2++;
}
Your question is somewhat unclear. Do you always want to add 5 stars to the string? If so, a constant string with 5 stars in it makes more sense than a loop. And I assume you really meant to do this for every element of gradeN? So something like this:
ArrayList<String> gradeN = new ArrayList<String>();
gradeN.add("one");
gradeN.add("two");
for (int i = 0; i < gradeN.size(); i++) {
gradeN.set(i, gradeN.get(i) + "*****");
System.out.println(gradeN.get(i));
}
If the number of stars added may vary and you really wanted to append them in a loop, then you could use StringBuilder to build it up:
ArrayList<String> gradeN = new ArrayList<String>();
gradeN.add("one");
gradeN.add("two");
int num = 5;
for (int i = 0; i < gradeN.size(); i++) {
StringBuilder stars = new StringBuilder(gradeN.get(i));
for (int j = 0; j < num; j++) {
stars.append('*');
}
gradeN.set(i, stars.toString());
System.out.println(gradeN.get(i));
}
One solution is to get the value of gradeN.get(0) on every loop and append * to it.
i.e.:
int num2 = 0;
while (num2<5){
gradeN.set(0, gradeN.get(0)+"*");
num2++;}
Output:
one*****
Demo:
http://ideone.com/XQvWqX

Categories