I'm trying to display array list indexing from a inconstant size of array from an object. How do iterate an arraylist that have inconsistent of size within to prevent IndexOutOfBoundsException.
public static void main(String[] args) {
Hello b = new Hello();
System.out.println("test 1 =" +b.Apple().get(0));
System.out.println("test 2 =" +b.Apple().get(1));
System.out.println("test 3 =" +b.Apple().get(2));
}
Hello.java file which return result of inconsistent index list
public ArrayList<Integer> Apple(){
ArrayList<Integer> values = new ArrayList<Integer>();
rs = db.getSM().executeQuery("SELECT a, b, count(*) AS rowCount from table");
while(rs.next()) {
values.add(rs.getInt("count"));
}
return values;
Expected result
First run, it only have 2 element. so it will print
test 1 = 23
test 2 = 13
test 3 = 0
Second run, it will have 3 element. so it will print
test 1 = 23
test 2 = 10
test 3 = 3
Sample solutions if you can omit the test 3 = 0 mention when there are only two elements :
for(int index=0; index<yourList.size(); index++) {
Object element=yourList.get(index);
// do something with the element (and its index if needed)
}
for(Object element : yourList) {
//do something with the element
}
Iterator<Object> it = yourList.iterator();
while (it.hasNext()) {
Object element = it.next();
//do something with your element
}
yourList.forEach(element -> /* do something with your element */);
Apart from the first solution providing an index, all these solutions are functionally equivalent.
Don't use Object as I did for the element type, you should obviously use the type of your elements instead.
To produce your current output the first solution seems the most adequate since it provides an index :
ArrayList<Integer> yourList = b.Apple();
for (int index=0; index < yourList.size(); index++) {
System.out.printf("test %d = %d", index + 1, yourList.get(index));
}
(printf takes a string template and a list of parameters for this template ; here %d represents numbers, the first occurence is replaced by the 1-based index and the second by the list element's value)
If you don't want to omit the test 3 = 0 output, I think Federico klez Culloca's suggestion to create a generator is best, but since I'm not familiar with them I'll instead provide a solution that adds zeroes to the list until it reaches the target size :
ArrayList<Integer> yourList = b.Apple();
int desiredSize=3;
int missingZeroes = desiredSize - yourList.size();
for(int addedZeroes=0; addedZeroes < missingZeroes; addedZeroes++) {
yourList.add(0);
}
//then proceed with the above List traversal solutions.
Related
This question already has answers here:
Java - How to find count of items in a list in another list
(8 answers)
List difference in java
(11 answers)
Common elements in two lists
(15 answers)
Intersection of Two Lists Objects in java 8
(2 answers)
Closed 1 year ago.
For example we have two ArrayList
ArrayList<Integer> first = new ArrayList<>();
ArrayList<Integer> second = new ArrayList<>();
And lets say we add some numbers to them:
first.add(1);
first.add(2);
second.add(2);
second.add(3);
And how to check here the condition like:
if(first.contains(second(element))){cnt++;(just increment hypothetical counter)}
Thanks
You can use Stream API to filter and count the elements in the second list.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> first = new ArrayList<>();
ArrayList<Integer> second = new ArrayList<>();
first.add(1);
first.add(2);
second.add(2);
second.add(3);
second.add(2);
first.forEach(n -> System.out
.println(n + " exists " + second.stream().filter(e -> e == n).count() + " times in the second list"));
}
}
Output:
1 exists 0 times in the second list
2 exists 2 times in the second list
Alternatively, you can use Collections#frequency to print the frequency of each number of the list, first in the list, second:
for (Integer x : first) {
System.out.println(x + " exists " + Collections.frequency(second, x) + " times in the second list");
}
Alternatively, you can use the nested loops to iterate the list, second for each number in the list, first:
for (Integer x : first) {
int count = 0;
for (Integer y : second) {
if (x == y)
count++;
}
System.out.println(x + " exists " + count + " times in the second list");
}
Simpler version of code. I wasn't quite sure from the question what exactly you are looking for. So I have added code for two methods.
One that returns count of unique elements which are not present in list 2 but available in list 1.
The other method returns map with element and count of occurrence of that element present in both the lists.
public static void main(String[] args) {
ArrayList<Integer> first = new ArrayList<>();
ArrayList<Integer> second = new ArrayList<>();
first.add(1);
first.add(2);
first.add(2);
first.add(2);
first.add(2);
first.add(4);
second.add(2);
second.add(3);
second.add(2);
second.add(1);
int uniqueCount = getCountOfUniqueElements(first,second);
Map<Integer,Integer> countMap = getCountMap(first,second);
System.out.println("Count of unique Elements in First list that are not in second list="+uniqueCount);
countMap.forEach((key,value) -> System.out.println(key + " occurred " + value + " times in first list"));
}
/**
* Counts number of elements that are in first list but not in second list
* #param first
* #param second
* #return count
*/
private static int getCountOfUniqueElements(List<Integer> first,
List<Integer> second) {
if(first == null || first.isEmpty() || second == null || second.isEmpty()) //if lists are empty or null, count is 0
return 0;
Set<Integer> set = new HashSet<>(second); // Convert second list to set for faster search or constant time retrieval
int count = 0;
for(Integer element : first) {
if(!set.contains(element)) {
count++;
}
}
return count;
}
/**
* Counts number of elements that are in first list which are also available in second
* list
* #param first
* #param second
* #return map with key as first list element and value as number of its occurrences in first list
*/
private static Map<Integer,Integer> getCountMap(List<Integer> first,
List<Integer> second) {
if(first == null || first.isEmpty() || second == null || second.isEmpty()) //if lists are empty or null, return emptyMap
return Collections.emptyMap();
Set<Integer> set = new HashSet<>(second); // Convert second list to set for faster search or constant time retrieval
Map<Integer,Integer> countMap = new HashMap<>(); // Maintains count of occurrences of first list element present in second list.
for(Integer element : first) {
if(set.contains(element)) {
countMap.put(element, countMap.getOrDefault(element, 0)+1);
}
}
return countMap;
}
I have two ArrayLists. The first list contains some x number of elements these elements are again ArrayLists. The second list contains only integer values.
Second list size is always less than first list size Example of first list is: [[TC1,TC1_1],[,TC1_2],[TC2,TC2_1],[TC3,TC3_1][,TC3_2],[TC4,TC4_1][,TC4_2][,TC4_3],[TC5,TC5_1],[TC6,TC6_1]]
Example of second list is [0,2,3,5,8,9].This second Araylist elements points to 1st arraylist where the 1st element of individual ArrayList elements of first arraylist is not empty
Now the requirement is 1st list should be split into 6 lists where 6 is 2nd list size. Output should be as below.
Of the 6 new lists 1st list would contain elements of main list from 0th to 1st index. The 2nd list would contain elements of main list from 3rd index. The 3rd list would contain elements of main list from 4th to 5th index and so on..finally output will be as below
`[[[TC1,TC1_1],[,TC1_2]]
[[TC2,TC2_1]]
[[TC3,TC3_1][,TC3_2]]
[[TC4,TC4_1][,TC4_2][,TC4_3]]
[[TC5,TC5_1]]
[[TC6,TC6_1]]]
private ArrayList getTCsIncludingSubTcs(ArrayList TCIndexes,ArrayList alTCs) {
//List tempSubList=new ArrayList();
ArrayList finalTCS=new ArrayList();
for(int j=0;j<TCIndexes.size();j++){
int TCIndex=(int)TCIndexes.get(j);
if(j==0 && TCIndexes.size()==1){
//List tempSubList=new ArrayList(alTCs.subList(TCIndex,(int)alTCs.size()));
List tempSubList=getSubArrayList(TCIndex,(int)alTCs.size(),alTCs);
finalTCS.add(tempSubList);
break;
}
int nextTCIndex=j+1;
System.out.println(nextTCIndex);
if(j==TCIndexes.size()-1){
List tempSubList=getSubArrayList(TCIndex,(int)alTCs.size(),alTCs);
finalTCS.add(tempSubList);
break;
}
List tempSubList=getSubArrayList(TCIndex,(int)alTCs.size(),alTCs);
finalTCS.add(tempSubList);
System.out.println("finalTCS :"+finalTCS);
}
System.out.println("fc size"+finalTCS.size());
return finalTCS;
}
Try this code.
public class Test {
private List<List<String>> getTcsIncludingSubTcs(ArrayList<Integer> tcIndexes,ArrayList<String> alTcs) {
List<List<String>> finalTcs=new ArrayList<>();
List<String> temp = new ArrayList<>();
int size = tcIndexes.size();
int i= alTcs.size();
int k = 0;
for(int j=0; j<alTcs.size(); j++){
if(( j != 0 && j % size == 0 && i >= size))
{
temp = new ArrayList<>();
k++;
}
i--;
temp.add(alTcs.get(j));
if(finalTcs.contains(temp))
finalTcs.remove(k);
finalTcs.add(k, temp);
}
return finalTcs;
}
public static void main (String arg[])
{
ArrayList<String> data1 = new ArrayList<>();
data1.add("TC1");
data1.add("TC2");
data1.add("TC3");
data1.add("TC4");
data1.add("TC5");
data1.add("TC6");
data1.add("TC7");
data1.add("TC8");
data1.add("TC9");
data1.add("TC10");
ArrayList<Integer> data2 = new ArrayList<>();
data2.add(0);
data2.add(3);
data2.add(6);
Test t = new Test();
List<List<String>> list = t.getTcsIncludingSubTcs(data2, data1);
for(List<String> l : list)
System.out.println(l);
}
}
Output:
[TC1, TC2, TC3]
[TC4, TC5, TC6]
[TC7, TC8, TC9, TC10]
One more solution is ,
we have source list and start index list.Using these two lists generate end index list.Now use start index list and end index list to generate the required final output
I am building a mind game, it's hard to explain so I put an example.
I have a list of words (it can be infinite):
String myList[] = {"chair", "house", "ocean", "plane", "dog", "TV", "grass", "money" etc....}
Now the tricky part, I need to build 4 lists of pair index/word (every list has the same size) randomly but that fit these rule:
if I chose a number, the word that match this number only appears in 2 lists.
for example this would be correct:
List1:
1/chair
2/house
3/plane
4/grass
List2
1/chair
2/dog
3/plane
4/TV
List3:
1/ocean
2/house
3/money
4/TV
List4
1/ocean
2/dog
3/money
4/grass
For example:
If I pick number 3, then list 3 and list 4 match the word 'money', list 1 and 2 match the word 'plane'. There always must be 2 matching lists (never less, never more). They should be build from a huge array of words randomly, so you can't guess which list will be matching when you pick a number.
I tried to do it with a nice simple recursive algorithm. But I badly failed.
My initial approach to this problem would be to
Select a random word in the universe
Assign the selected word to two lists that
are different and
are not full
Store the random word in a set of closed words in case it is selected again
Rinse and repeat until all lists are full
Something like this should do the trick (you can change the provided words and the respective listSize accordingly). The number of words should be dividable by the listSize in order to fill up all lists.
public static void main(String[] args) {
String[] words = new String[] { "chair", "house", "ocean", "plane",
"dog", "TV", "grass", "money" };
// valid list sizes for 8 words: 1, 2, 4, 8
int listSize = 4;
List<String[]> result = distributeRandomly(words, listSize);
for (String[] resultList : result) {
for (int index = 0; index < listSize; index++) {
System.out.println((index + 1) + "/" + resultList[index]);
}
System.out.println();
}
}
private static List<String[]> distributeRandomly(String[] words, int listSize) {
// each word goes into 2 lists, so how many lists do we need?
int listCount = words.length * 2 / listSize;
if (listCount * listSize != words.length * 2) {
throw new IllegalArgumentException("Number of words"
+ " must be a multiple of the size of the individual lists!");
}
// initialize result lists (here arrays) in fitting size
List<String[]> listsToFill = new ArrayList<String[]>(listCount);
for (int index = 0; index < listCount; index++) {
listsToFill.add(new String[listSize]);
}
// be sure to randomly pick the given words by shuffling them
List<String> shuffledWords = new ArrayList<String>(Arrays.asList(words));
Collections.shuffle(shuffledWords);
List<String[]> result = new ArrayList<String[]>(listCount);
int maxWordPosition = listSize - 1;
// distribute words
for (String word : shuffledWords) {
// word is supposed to be inserted in two lists at the same index
int wordPosition = -1;
// iterate result lists
Iterator<String[]> listIterator = listsToFill.iterator();
while (listIterator.hasNext()) {
String[] list = listIterator.next();
if (wordPosition == -1) {
// look out for the first list with an empty slot
for (int index = 0; index < listSize; index++) {
if (list[index] == null) {
// found empty slot at this index
wordPosition = index;
// insert word here (first list)
list[wordPosition] = word;
if (wordPosition == maxWordPosition) {
// the list is full, no more empty slots here
listIterator.remove();
result.add(list);
}
break;
}
}
} else if (list[wordPosition] == null) {
// found second list with an empty slot at the same index
list[wordPosition] = word;
if (wordPosition == maxWordPosition) {
// the list is full, no more empty slots here
listIterator.remove();
result.add(list);
}
// we are done with this word
break;
}
}
// shuffle result lists again, to ensure randomness
Collections.shuffle(listsToFill);
}
return result;
}
This produces (for example) the following output:
1/grass
2/TV
3/plane
4/ocean
1/grass
2/dog
3/money
4/chair
1/house
2/dog
3/money
4/ocean
1/house
2/TV
3/plane
4/chair
I build removing duplicates, however I'm thinking how to use a method that removes the duplicate elements from an array list of integers using the following header:
public static void removeDuplicate(ArrayList<Integer> list)
write a test program that prompts the user to enter 10 integers to a list and
displays the distinct integers separated by exactly one space.
import java.util.ArrayList;
import java.util.Scanner;
public class RemoveDuplicates {
public static void main(String[] args){
ArrayList<Integer>list = new ArrayList<Integer>();
Scanner input = new Scanner (System.in);
System.out.print("Enter integers (input ends with 0): ");
int value;
do{
value = input.nextInt();
if(!list.contains(value)&& value !=0)
list.add(value);
}while (value !=0);
input.close();
for (int i = 0; i < list. size(); i++)
System.out.print(list.get(i) + " ");
}
}
It's my code,please modifying please, how to use method and test .
If I understand correctly, you should implement a method with this header
public static void removeDuplicate(ArrayList<Integer> list)
judging by its name, I'd say that method should remove the duplicates from the list and not (as you are doing it right now) the do-while-loop during input.
So first remove the check in your loop (if(!list.contains(value)&& value !=0)) and just add every number the user types to the list.
Then you can make a call to the method removeDuplicate(list);. If you want you can add this call in your loop and it will be executed after every input or you execute it just once when the input is closed.
Now implementing the method:
public static void removeDuplicate(ArrayList<Integer> list) { // this is the header you need to use
The problem here is, the method knows the list but not the element that is a possible duplicate. So you have to look for it
for (int i = 0; i < list.size(); i++) { // iterate through every element in the list
Integer current = list.get(i); // for convenience, save the current list item in a variable
So, you check every integer in the list – one by one.. but if you want to know if the integer exists a second time, you have to search the tail of the list. Meaning you have to check the sublist after i.
List sublist = list.subList(i + 1, list.size()); // the sublist with all elements of the list from i+1 to the end
your list.contains(value) line is correct, you can use it here as well. Only now you call it on the sublist
if(sublist.contains(current)){ // checks if the number is in the sublist
sublist.remove(current); // removes the number from the sublist
}
This however would only remove the first duplicate. Alternatively, you can remove every item in the list that equals the current integer:
while (sublist.contains(current)) {
sublist.remove(current);
}
And that's it. Your method is finished.
}
}
It is finished because you are actually working on the one and only list in your program. Even when you remove an integer from your sublist, it is actually removed from the sublist and the real list (the sublist is just a reference, and not an actual list on its own)
EDIT
for your convenience here the complete code with both methods. If you compare the code to yours, you'll see that there is not much different:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
System.out.print("Enter integers (input ends with 0): ");
int value;
do {
value = input.nextInt();
if (value != 0) { // this changed: add every number except 0
list.add(value);
}
} while (value != 0);
input.close();
removeDuplicate(list); // here you make the call for the new method
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
}
// and this is the new method
public static void removeDuplicate(ArrayList<Integer> list) {
for (int i = 0; i < list.size(); i++) {
Integer current = list.get(i);
List sublist = list.subList(i + 1, list.size());
while (sublist.contains(current)) {
sublist.remove(current);
}
}
}
If you don't want duplicate, use a collection that implements the Set interface (http://docs.oracle.com/javase/7/docs/api/java/util/Set.html) instead of an array list.
I'm writing a method that allows me to count how many times an element of type String shows up in a LinkedList of type Strings. my code shown below does not work. I keep getting index out of bounds in the line i commented on down below. Can't seem to find the bug
public int findDuplicate (LinkedList<String> e) {
int j = 1;
LinkedList<String> test = e;
while (!test.isEmpty()){
test = e;
String value = test.pop();
//Screws up here when i = 6
for(int i =0; i<=test.size() && test.get(i)!=null; i++){
String value3 = test.get(i);
if(e.get(i).equals(value) && i<=test.size()){
String value2 = test.get(i);
j++;
String Duplicate = e.get(i);
e.remove(i);
}
}
System.out.println(value + " is listed " + j + " times");
}
return j;
}
using hashmaps.. still doesn't work
public void findDuplicate (LinkedList e) {
Map<String,Integer> counts = new HashMap<String,Integer>();
while(!e.isEmpty()){
String value = e.pop();
for(int i =0; i<e.size(); i++){
counts.put(value, i);
}
}
System.out.println(counts.toString());
}
My code should go through the linked list find out how many times an element within the list appears and deletes duplicates from the list at the same time. Then prints the element and the number of times it appears in the list. I posted about this last night but didn't get a response yet. Sorry for the repost.
You are running off the end of the list. Change
for(int i =0; i<=test.size() && test.get(i)!=null; i++){
to
for(int i =0; i< test.size() && test.get(i)!=null; i++){
Valid indexes for a List (or an array) are 0 through size() - 1.
Regarding your hashmap example to count the duplicates:
#Test
public void countOccurrences() {
LinkedList<String> strings = new LinkedList<String>(){{
add("Fred");
add("Fred");
add("Joe");
add("Mary");
add("Mary");
add("Mary");
}};
Map<String,Integer> count = count(strings,new HashMap<String,Integer>());
System.out.println("count = " + count);
}
private Map<String, Integer> count(List<String> strings, Map<String, Integer> runningCount) {
if(strings.isEmpty()) {
return runningCount;
}
String current = strings.get(0);
int startingSize = strings.size();
while(strings.contains(current)) {
strings.remove(current);
}
runningCount.put(current, startingSize - strings.size());
return count(strings,runningCount);
}
If you want the original strings list preserved you could do
Map<String,Integer> count = count(new LinkedList<String>(strings),new HashMap<String,Integer>());
System.out.println("strings = " + strings);
System.out.println("count = " + count);
Check out google's guava collections which has a perfect class for maintaining a map and getting a count:
https://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap
Multiset<String> wordsMultiset = HashMultiset.create();
wordsMultiset.addAll(words);
// now we can use wordsMultiset.count(String) to find the count of a word
I hope you realize what the test = e statement is doing. After this statement executes both test and e refer to the same object.
If anyone of them modifies the list, the other sees it as they both are looking at the same object.
If this is not intended you need to clone the list before assigning it to another list reference.
This doesn't affect your out of bounds issue, but you are removing elements from your list while still evaluating it. If you remove an element, you should call i-- afterwards, or you skip the next entity (which is re-indexed) for evaluation.
Also of note regarding your code, I see you are trying to make a copy of your list, but standard assignment means test and e both point to the same instance. You need to use Collections.copy() see this SO thread on how to use the class.