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;
}
Related
I have several lists. Monthly lists. The objects contained in them have a value. The goal is to subtract the value of the first monthobject from the value of the second monthobject.
and save the new value
next step is to subtract the original value of the second month from the third month value. and safe the new third month value. the original value of the third month is to subtract from the fourth one etc. etc.
Now, what i have done among other variants, but I think that's the closest I get.
This is one of my attempts:
//creates multiple ArrayLists in List, based on numbers of monthList
for (int i = 0; i < monthList.size(); i++) {
monthyList.add(new ArrayList<>());
}
List<Objecty> finalList = new ArrayList<>();
for (int i = 0; i < monthyList.size(); i++) {
List<Object> firstMonthList = monthyList.get(i);
List<Object> nextMonthList = monthyList.get(i + 1);
List<Object> copyOfNextList = List.copyOf(nextMonthList);
for (int j = 0; j < firstMonthList.size(); j++) {
Object firstMonthObject = firstMonthList.get(j);
for (int k = 0; k < copyOfNextList.size(); k++) {
Object nextMonthObject = copyOfNextList.get(k);
if (nextMonthObject.getAccountNumber() == firstMonthObject.getAccountNumber()) {
nextMonthObject.setAmount(subtractAmount(firstMonthObject.getAmount(),nextMonthObject.getAmount()));
finalList.add(nextMonthObject);
break;
}
}
}
finalList.add....
}
So unfortunately I cannot get any further... does it have any advantages to use LinkedList for this case?
I hope the problem is understandably.
Can you help me improve the code? Or are there better approaches to solve this problem?
I have a List<Integer> with the values (3,3,2,3,4). How can I check each of all the values from an array are equal to? For example, int value = 3.
for(int i = 0; i < list.size(); i++) {
//check all the values from the array
}
You can use contains function exposed by the list.
int value = ...;
List<Integer> list = ....;
if (list.contains(value))
// do your stuff
else
// do else stuff
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.
This question already has answers here:
How to efficiently remove duplicates from an array without using Set
(48 answers)
Closed 8 years ago.
I have written a method to count the number of occurrences of the words in a word file. Prior, in another method, i have sorted the words to appear in alphabetical order. There for a sample input into this method will look like this:
are
away
birds
birds
going
going
has
My question is.. How do i delete the repeated occurrences in this method? (after counting ofcoz) I have tried to use another string array to copy the unique ones into that string array, but i get a null pointer exception.
public static String[] counter(String[] wordList)
{
for (int i = 0; i < wordList.length; i++)
{
int count = 1;
for(int j = 0; j < wordList.length; j++)
{
if(i != j) //to avoid comparing itself
{
if (wordList[i].compareTo(wordList[j]) == 0)
{
count++;
}
}
}
System.out.println (wordList[i] + " " + count);
}
return wordList;
}
Any help will be much appreciated.
Oh, and my current output looks something like this:
are 1
away 1
birds 2
birds 2
going 2
going 2
has 1
I would prefer using Map to store word occurrence. Keys in the map are stored in Set so it can't be duplicated. What about something like this?
public static String[] counter(String[] wordList) {
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < wordList.length; i++) {
String word = wordList[i];
if (map.keySet().contains(word)) {
map.put(word, map.get(word) + 1);
} else {
map.put(word, 1);
}
}
for (String word : map.keySet()) {
System.out.println(word + " " + map.get(word));
}
return wordList;
}
I already posted an answer on this question. Your question is almost identical - he was having problems creating another array and getting an NPE too.
This is what I came up with (assuming the array is sorted):
public static String[] noDups(String[] myArray) {
int dups = 0; // represents number of duplicate numbers
for (int i = 1; i < myArray.length; i++)
{
// if number in array after current number in array is the same
if (myArray[i].equals(myArray[i - 1]))
dups++; // add one to number of duplicates
}
// create return array (with no duplicates)
// and subtract the number of duplicates from the original size (no NPEs)
String[] returnArray = new String[myArray.length - dups];
returnArray[0] = myArray[0]; // set the first positions equal to each other
// because it's not iterated over in the loop
int count = 1; // element count for the return array
for (int i = 1; i < myArray.length; i++)
{
// if current number in original array is not the same as the one before
if (!myArray[i].equals(myArray[i-1]))
{
returnArray[count] = myArray[i]; // add the number to the return array
count++; // continue to next element in the return array
}
}
return returnArray; // return the ordered, unique array
}
Sample input/output:
String[] array = {"are", "away", "birds", "birds", "going", "going", "has"};
array = noDups(array);
// print the array out
for (String s : array) {
System.out.println(s);
}
Outputs:
are
away
birds
going
has
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;
}