I am looking to remove the element from an array list, the user has to input the element to be removed. At the moment my Iterator seems to be wrong. User inputs the Car Model, Color, ID Plate, Number of doors. User has to input the id and it should delete the whole element
Brand is :Nissan Color is Black ID is LS57GHT Door is 4 (this should be all deleted when user inputs the correct ID).
This is what I am using :
ArrayList<String> List;
List = new ArrayList<>(maxCapacity);
for (Iterator<String> iterator = List.iterator(); iterator.hasNext();) {
String id = input.next();
if (List.equals(id)) {
iterator.remove();
}
}
You actually need to get the current element of the iterator by calling
String current = iterator.next();
inside your loop.
You are prompting the user to enter a number (assuming your input is actually a Scanner that you declared somewhere earlier) in every iteration of your loop. You should move that call out of the loop.
You want to compare the currently iterated element (see 1.) to the ID entered by the user. At the moment you are comparing your entire ArrayList object to the ID string, which will always be false.
Change your code as in example:
public static void main(String[] args) {
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
System.out.println("Input ID you want remove: ");
Scanner scanner = new Scanner(System.in);
String inputId = scanner.nextLine();
System.out.println("List before removing: " + list);
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
String id = iterator.next();
if (id.equals(inputId)) {
iterator.remove();
break;
}
}
System.out.println("List after removing: " + list);
}
You'll get the following output:
Input ID you want remove:
a
List before removing: [a, b, c]
List after removing: [b, c]
Example can be reproduced here.
And never use a capital letters to name your variables, it makes code unreadable and sometimes confusing. In your case ArrayList named List looks like java.util.List interface.
Related
I have in my main class this code:
System.out.println("pls enter the id that you are looking for");
String id = keyboard.nextLine();
for(int k=0;k<elements.size();k++){
elements.Hotell.get_Idset().equals(id);
}
And I want to search for a id into my ArrayList that is full of objects.
First I read the id(String) from the keyboard and I want to compare with my ArrayList to find if this id exists.
Also the method get_Idset() belongs to Class Hotell,
so I am getting an error:
cannot find symbol variable Hotell
I did not find an answer.
My ArrayList:
ArrayList<Object> elements = new ArrayList<Object>();
You need to make the following changes:
Make elements list of Hotell and not Object instances, e.g.:
ArrayList<Hotell> elements = new ArrayList<Hotell>();
Iterate the list and use get_Idset() (assuming it returns a String) to get and compare the id
Below is the example:
ArrayList<Hotell> elements = new ArrayList<Hotell>(); //Your list
String id = keyboard.nextLine();
Optional<String> element = elements.stream()
.filter(e -> e.get_Idset().equals(id))
.findFirst();
if(element.isPresent()){
System.out.println("Element found");
}else{
System.out.println("Element not found");
}
completely new to Java, I am trying to find the matched element from one array into another, cannot seem to understand how to do it. Here is a sample of how the data is and how far I've gotten:
In this code and after printing this line, this is how the data is:
ArrayList<String> all_accounts = new ArrayList<String>();
all_accounts.add(acc);
System.out.println("\nArray 1:" + all_accounts);
Result Array 1:
Array 1:[77737320]
Array 1:[88405378]
Array 1:[00056893]
Array 1:[10709816]
ArrayList<String> cancel_accounts = new ArrayList<String>();
cancel_accounts.add(cancel_acc);
System.out.println("\nArray 2:" + cancel_accounts);
Results from Array 2:
Array 2:[77737320]
Array 2:[]
Array 2:[]
Array 2:[]
Stack here, I still cant understand why it doesn't match:
String found = null;
for (String account: all_accounts) {
for (String canceled: cancel_accounts) {
System.out.println(canceled);
found = canceled;
}
System.out.println(found);
if(account.equals(found) ) {
System.out.println(account);
}
}
I need to find the matched element, 77737320 in this case.
Thanks for looking!
+1 for answer from user6904265
However, You need not create a new HashSet. You can use ArrayList.retainAll(). If you want to maintain the all_accounts list, create a new clone and use that instead.
You could implement this as intersection between sets:
Set<String> set_all_account = new HashSet<String>(all_accounts);
Set<String> set_cancel_accounts = new HashSet<String>(cancel_accounts);
set_all_account.retainAll(set_cancel_accounts);
set_all_account.forEach(x -> System.out.println("Element matched: "+x));
Or as said by kartiks in his comment you could call the retainAll method directly on the all_accounts array:
all_accounts.retainAll(cancel_accounts);
all_accounts.forEach(x -> System.out.println("matched element: "+x));
Pay attention with this solution because in this case retainAll applies directly on the ArrayList and modifies it (as you can see the final result is in the all_accounts array). Moreover duplicate elements remain in the result array.
Last implementation (if you want compute intersection and print the result all in one line, also this version keeps duplicate elements):
all_accounts.stream().filter(x -> cancel_accounts.contains(x)).forEach(x -> System.out.println("matched element: "+x));
You can loop through the one list and search the second list for each element in first.
for (String account: all_accounts) {
if (cancel_accounts.contains(account) {
// Match found - do something....
System.out.println(account);
}
}
Just add an equals check to your for - loops (will work even without List#contains method)
for(String account: all_accounts) {
System.out.println(account);
for(String canceled: cancel_accounts){
System.out.println(canceled);
if(account.equals(cancelled)){
//you've found first intersection, cancelled exists in both
System.out.println(canceled + " is the same as " + account);
}
}
}
I have an arraylist with bankcustomers. Some customers occur more than once (this happens if they have more than one account).
Now I want to print all the customers, but if then occur more than once I only want to print them once.
Heres is my non working code. As it is now it prints the whole list. How can I add code to only print duplicates once?
public void showCustomers() {
private ArrayList<Customer> customers = new ArrayList<Customer>();
for(Customer c: customers) {
System.out.println("First name: " + c.getFirstname());
System.out.println("Last name: " + c.getLastname());
System.out.println("Customer number: " + c.getNumber());
for(Account a : c.getAccounts()) {
System.out.println("Account number: " + a.getAccountId());
}
}
}
I prefer not to use HashSet (if it's not neccesary). I'm trying to learn ArrayLists now.
Add all your elements to a Set:
for (Customer c: new HashSet<Customer>(customers)) {
From the linked Javadoc:
A collection that contains no duplicate element
Whenever you need need to avoid duplicates, think Set
List<String> lst = Arrays.asList("Foo", "Foo", "Bar", "Baz");
for(String s : new HashSet<>(lst)) {
System.out.println(s);
}
If the Customer class already implements hashCode and equals in the way you expect it you can just use a Set.
Set<Customer> uniqueCustomers = new HashSet<Customer>(customers);
if you need to keep the original order of the elements in the List use a LinkedHashSet
Set<Customer> uniqueOrderedCustomers = new LinkedHashSet<Customer>(customers);
if the Customer class does not implement hashCode and equals or you can't implement it, because you don't have the sources, use a TreeSet and implement a Comparator.
Optimally, you'll want to create a parallel array within the showCustomers() method.
Have the array contain a relative boolean value.
Within the for(Customer c: customers) iteration create (nest) a conditional statement (an if, else).
From within the conditional, acquire the value at the nth index of the parallel array.
If the current value is false set it to true and print out to the console.
If the current value is true, then call the continue statement to have the iteration go to the next item (and not print to the console).
The following will print the first Customer of the duplicate or multiple entries:
public void showCustomers() {
// Visibility of variables in class methods is irrelevant
// All variables/values created within a method will only be
// accessible from within it's scope
/*private*/ ArrayList<Customer> customers = new ArrayList<Customer>();
// Create a parallel list
List<Boolean> customers_b = new ArrayList<Boolean>(customers.size());
// Use this value to hold the index of your current item
int n = 0;
for(Customer c: customers) {
if(customers_b.get(n) == false)
{
System.out.println("First name: " + c.getFirstname());
System.out.println("Last name: " + c.getFirstname());
System.out.println("Customer number: " + c.getNumber());
for(Account a : c.getAccounts()) {
System.out.println("Account number: " + a.getAccountId());
}
customers_b.set(n, true);
n++;
}
else
{
n++;
continue;
}
}
}
convert your list into a Hashset and this will do the trick, since hashsets doesn't allow duplicate values to be stored but in case of HashMap and if there's a duplicate, it replaces the old value with the new one.
I have to count the number of unique words from a text document using Java. First I had to get rid of the punctuation in all of the words. I used the Scanner class to scan each word in the document and put in an String ArrayList.
So, the next step is where I'm having the problem! How do I create a method that can count the number of unique Strings in the array?
For example, if the array contains apple, bob, apple, jim, bob; the number of unique values in this array is 3.
public countWords() {
try {
Scanner scan = new Scanner(in);
while (scan.hasNext()) {
String words = scan.next();
if (words.contains(".")) {
words.replace(".", "");
}
if (words.contains("!")) {
words.replace("!", "");
}
if (words.contains(":")) {
words.replace(":", "");
}
if (words.contains(",")) {
words.replace(",", "");
}
if (words.contains("'")) {
words.replace("?", "");
}
if (words.contains("-")) {
words.replace("-", "");
}
if (words.contains("‘")) {
words.replace("‘", "");
}
wordStore.add(words.toLowerCase());
}
} catch (FileNotFoundException e) {
System.out.println("File Not Found");
}
System.out.println("The total number of words is: " + wordStore.size());
}
Are you allowed to use Set? If so, you HashSet may solve your problem. HashSet doesn't accept duplicates.
HashSet noDupSet = new HashSet();
noDupSet.add(yourString);
noDupSet.size();
size() method returns number of unique words.
If you have to really use ArrayList only, then one way to achieve may be,
1) Create a temp ArrayList
2) Iterate original list and retrieve element
3) If tempArrayList doesn't contain element, add element to tempArrayList
Starting from Java 8 you can use Stream:
After you add the elements in your ArrayList:
long n = wordStore.stream().distinct().count();
It converts your ArrayList to a stream and then it counts only the distinct elements.
I would advice to use HashSet. This automatically filters the duplicate when calling add method.
Although I believe a set is the easiest solution, you can still use your original solution and just add an if statement to check if value already exists in the list before you do your add.
if( !wordstore.contains( words.toLowerCase() )
wordStore.add(words.toLowerCase());
Then the number of words in your list is the total number of unique words (ie: wordStore.size() )
This general purpose solution takes advantage of the fact that the Set abstract data type does not allow duplicates. The Set.add() method is specifically useful in that it returns a boolean flag indicating the success of the 'add' operation. A HashMap is used to track the occurrence of each original element. This algorithm can be adapted for variations of this type of problem. This solution produces O(n) performance..
public static void main(String args[])
{
String[] strArray = {"abc", "def", "mno", "xyz", "pqr", "xyz", "def"};
System.out.printf("RAW: %s ; PROCESSED: %s \n",Arrays.toString(strArray), duplicates(strArray).toString());
}
public static HashMap<String, Integer> duplicates(String arr[])
{
HashSet<String> distinctKeySet = new HashSet<String>();
HashMap<String, Integer> keyCountMap = new HashMap<String, Integer>();
for(int i = 0; i < arr.length; i++)
{
if(distinctKeySet.add(arr[i]))
keyCountMap.put(arr[i], 1); // unique value or first occurrence
else
keyCountMap.put(arr[i], (Integer)(keyCountMap.get(arr[i])) + 1);
}
return keyCountMap;
}
RESULTS:
RAW: [abc, def, mno, xyz, pqr, xyz, def] ; PROCESSED: {pqr=1, abc=1, def=2, xyz=2, mno=1}
You can create a HashTable or HashMap as well. Keys would be your input strings and Value would be the number of times that string occurs in your input array. O(N) time and space.
Solution 2:
Sort the input list.
Similar strings would be next to each other.
Compare list(i) to list(i+1) and count the number of duplicates.
In shorthand way you can do it as follows...
ArrayList<String> duplicateList = new ArrayList<String>();
duplicateList.add("one");
duplicateList.add("two");
duplicateList.add("one");
duplicateList.add("three");
System.out.println(duplicateList); // prints [one, two, one, three]
HashSet<String> uniqueSet = new HashSet<String>();
uniqueSet.addAll(duplicateList);
System.out.println(uniqueSet); // prints [two, one, three]
duplicateList.clear();
System.out.println(duplicateList);// prints []
duplicateList.addAll(uniqueSet);
System.out.println(duplicateList);// prints [two, one, three]
public class UniqueinArrayList {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer();
List al=new ArrayList();
al.add("Stack");
al.add("Stack");
al.add("over");
al.add("over");
al.add("flow");
al.add("flow");
System.out.println(al);
Set s=new LinkedHashSet(al);
System.out.println(s);
Iterator itr=s.iterator();
while(itr.hasNext()){
sb.append(itr.next()+" ");
}
System.out.println(sb.toString().trim());
}
}
3 distinct possible solutions:
Use HashSet as suggested above.
Create a temporary ArrayList and store only unique element like below:
public static int getUniqueElement(List<String> data) {
List<String> newList = new ArrayList<>();
for (String eachWord : data)
if (!newList.contains(eachWord))
newList.add(eachWord);
return newList.size();
}
Java 8 solution
long count = data.stream().distinct().count();
Say I have a List like:
List<String> list = new ArrayList<>();
list.add("a");
list.add("h");
list.add("f");
list.add("s");
While iterating through this list I want to add an element at the end of the list. But I don't want to iterate through the newly added elements that is I want to iterate up to the initial size of the list.
for (String s : list)
/* Here I want to add new element if needed while iterating */
Can anybody suggest me how can I do this?
You can't use a foreach statement for that. The foreach is using internally an iterator:
The iterators returned by this class's iterator and listIterator
methods are fail-fast: if the list is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException.
(From ArrayList javadoc)
In the foreach statement you don't have access to the iterator's add method and in any case that's still not the type of add that you want because it does not append at the end. You'll need to traverse the list manually:
int listSize = list.size();
for(int i = 0; i < listSize; ++i)
list.add("whatever");
Note that this is only efficient for Lists that allow random access. You can check for this feature by checking whether the list implements the RandomAccess marker interface. An ArrayList has random access. A linked list does not.
Iterate through a copy of the list and add new elements to the original list.
for (String s : new ArrayList<String>(list))
{
list.add("u");
}
See
How to make a copy of ArrayList object which is type of List?
Just iterate the old-fashion way, because you need explicit index handling:
List myList = ...
...
int length = myList.size();
for(int i = 0; i < length; i++) {
String s = myList.get(i);
// add items here, if you want to
}
You could iterate on a copy (clone) of your original list:
List<String> copy = new ArrayList<String>(list);
for (String s : copy) {
// And if you have to add an element to the list, add it to the original one:
list.add("some element");
}
Note that it is not even possible to add a new element to a list while iterating on it, because it will result in a ConcurrentModificationException.
I do this by adding the elements to an new, empty tmp List, then adding the tmp list to the original list using addAll(). This prevents unnecessarily copying a large source list.
Imagine what happens when the OP's original list has a few million items in it; for a while you'll suck down twice the memory.
In addition to conserving resources, this technique also prevents us from having to resort to 80s-style for loops and using what are effectively array indexes which could be unattractive in some cases.
To help with this I created a function to make this more easy to achieve it.
public static <T> void forEachCurrent(List<T> list, Consumer<T> action) {
final int size = list.size();
for (int i = 0; i < size; i++) {
action.accept(list.get(i));
}
}
Example
List<String> l = new ArrayList<>();
l.add("1");
l.add("2");
l.add("3");
forEachCurrent(l, e -> {
l.add(e + "A");
l.add(e + "B");
l.add(e + "C");
});
l.forEach(System.out::println);
We can store the integer value while iterating in the list using for loop.
import java.util.*;
class ArrayListDemo{
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
List<Integer> list = new ArrayList<Integer>();
System.out.println("Enter the number of elements you wanna print :");
int n = scanner.nextInt();
System.out.println("Enter the elements :");
for(int i = 0; i < n; i++){
list.add(scanner.nextInt());
}
System.out.println("List's elements are : " + list);
/*Like this you can store string while iterating in java using forloop*/
List<String> list1 = new ArrayList<String>();
System.out.println("Enter the number of elements you wanna store or print : ");
int nString = scanner.nextInt();
System.out.println("Enter the elements : ");
for(int i = 0; i < nString; i++){
list1.add(scanner.next());
}
System.out.println("Names are : " + list1);
scanner.close();
}
}
Output:
Enter the number of elements you wanna print :
5
Enter the elements :
11
12
13
14
15
List's elements are : [11, 12, 13, 14, 15]
Enter the number of elements you wanna store or print :
5
Enter the elements :
apple
banana
mango
papaya
orange
Names are : [apple, banana, mango, papaya, orange]