How to remove multiple elements in Vector in Java? - java

I read from .txt file all of the ids and insert these ids into Vector.
String pathSelectedfile = fileChooser.getSelectedFile().getAbsolutePath();
File selectedFile = new File(pathSelectedfile);
Scanner readFile = new Scanner(selectedFile);
Vector ids=new Vector();
while (readFile.hasNextLine()) {
String id= readFile.nextLine();
ids.addElement(id);
}
then I want to remove multiple ids in Vector.i can do that by for loop
but information is too big.tnx a lot

To remove multiple values
Vector vector = new Vector();
vector.add("value1");
vector.add("value2");
vector.add("value3");
vector.add("value4");
System.out.println("Size : "+vector.size());
// to remove single value
vector.remove("value1");
System.out.println("Size : "+vector.size());
Vector itemsToRemove = new Vector();
itemsToRemove.add("value3");
itemsToRemove.add("value4");
//remove multiple values
vector.removeAll(itemsToRemove);
System.out.println("Size : "+vector.size());
//to remove all elements
vector.removeAllElements();
// or
vector.clear();
But instead of using Vector consider to use ArrayList since Vector is obsolete collection.
Read this : Why is Java Vector class considered obsolete or deprecated?
Also use generics Like ArrayList<String> idList = new ArrayList() if you store only String elements in list.
If you want to skip duplicates when adding elements in Vector, use the following code
Vector vector = new Vector() {
#Override
public synchronized boolean add(Object e) {
if(!contains(e)){
return super.add(e);
}
System.out.println("Element " + e +" is duplicate");
return false ;
}
};
But if you want to add only unique elements, use Set

Do completely remove the duplicated ids, you could use the following:
Set<String> ids=new LinkedHashSet<String>();
Set<String> duplicates=new HashSet<String>();
while (readFile.hasNextLine()) {
String id= readFile.nextLine();
if(!ids.add(id)) {
duplicates.add(id);
}
}
ids.removeAll(duplicates)
Note that unlike Vector, LinkedHashSet is not synchronized. In most cases this is not a bad thing, but in the case that you actually need it to be synchronized, wrap it using Collections.synchronizedSet()

READ the javadoc and pay attention to methods starting with remove http://docs.oracle.com/javase/6/docs/api/java/util/Vector.html. This should be you first approach not SO.

If you "want to remove multiple ids in Vector" do the following
ids = new Vector(new HashSet(ids))

Related

Best way to get unique list without changing the Order

I have a list of string or list of integers of 20,000 items
Now it contains duplicates...However i don't want to disturb the order of the item.
We can easily convert a list to Set for unique Set unique = new HashSet(list);
However the above breaks the sequential order of the items.
What would be the best approach for this?
Thanks.
You should use java.util.LinkedHashSet to get unique elements without changing the order:
Set<String> uniqueSet = new LinkedHashSet<>(list);
One other way is to use distinct():
list.stream().distinct().collect(Collectors.toList())
But distinct() uses LinkedHashSet internally. There is no need for unnecessary procedure.
So best way is using the LinkedHashSet constructor:
LinkedHashSet(Collection c) Constructs a new linked hash
set with the same elements as the specified collection.
You can try stream distinct
yourList.stream().distinct().collect(Collectors.toList());
Update1:
As I know, this is the best solution.
list.contains(element) will do 2 loop processes. One for iterate the element and add it to new list, one for check element is contained -> 0(n*n)
new LinkedHashSet() will created a new LinkedHashSet, and a new Arraylist output -> issue about memory. And the performance, i think it is equals with stream distinct
Update2: we must ensure that the output is a List, not a Set
As I know, stream distinct use HashSet internally. It is an more efficient memory implementation than LinkedHashSet (which is hash table and linked list implementation of the set interface) in our case.
Detail here
If you apply LinkedHashSet, the source code will something like below, so we have 1 ArrayList and 1 LinkedHashSet.
output = new ArrayList(new LinkedHashSet(yourList));
I did a small benchmark with 1k for-loop.
int size = 1000000;
Random rand = new Random((int) (System.currentTimeMillis() / 1000));
List<Integer> yourList = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
yourList.add(rand.nextInt(10000));
}
// test1: LinkedHashSet --> 35ms
new ArrayList<Integer>(new LinkedHashSet<Integer>(yourList));
// test2: Stream distinct --> 30ms
yourList.stream().distinct().collect(Collectors.toList());
If you don't want to break the order, then Iterate the list and make a new list as below.
ArrayList<Integer> newList = new ArrayList<Integer>();
for (Integer element : list) {
if (!newList.contains(element)) {
newList.add(element);
}
}
Try the bellow code
public static void main(String[] args) {
String list[] = {"9","1","1","9","2","7","2"};
List<String> unique = new ArrayList<>();
for(int i=0; i<list.length; i++) {
int count = unique.size();
if(count==0) {
unique.add(list[i]);
}else {
boolean available = false;
for(int j=0; j<count; j++) {
if(unique.get(j).equals(list[i])) {
available = true;
break;
}
}
if(!available) {
unique.add(list[i]);
}
}
}
//checking latest 'unique' value
for(int i=0; i<unique.size(); i++) {
System.out.println(unique.get(i));
}
}
It will return 9 1 2 7, but I haven't tried up to 20,000 collection lists, hopefully there are no performance issues
If you are trying to eliminate duplicates, you can use LinkedHashSet it will maintain the order.
if String
Set<String> dedupSet = new LinkedHashSet<>();
if Integer
Set<Integer> dedupSet = new LinkedHashSet<>();

Deleting specific object from ArrayList using for-loop

I am trying to delete one object from an ArrayList, but after iterating through the list with the for loop i'm stuck at what to do next. nameInput is a lowercase string from the user.
If i run this it prints the object from arr list equal to the input from nameInput. But I cannot understand how to go from printing that object to deleting it?
I'm sure this is a stupid question but the 50+ answers i have read and tried all seem to fail me (or more likely I fail to understand them). I have tried the list.remove and removeIf.
private ArrayList<Arr> arr = new ArrayList<>();
private void removeItem() {
for (Object arr : arr) {
if (((Arr) arr).getName().equals(nameInput())) {
System.out.println(arr);
break;
} else {
System.out.println("Error");
}
}
}
Using for loop
List<Arr> arr = new ArrayList<>();
for (Arr item : arr) {
if (item.getName().equals(nameInput())) {
arr.remove(item);
break;
}
}
If not call break after remove element, you get ConcurrentElementException
Note from #Aomine: you have to implement correct Arr.equals() method.
Using Iterator
List<Arr> arr = new ArrayList<>();
Iterator<Arr> it = arr.iterator();
while (it.hasNext()) {
Arr items = it.next();
if (item.getName().equals(nameInput())) {
it.remove();
break; // you can continue iterating and remove another item
}
}
Using Streams
List<Arr> arr = new ArrayList<>();
arr.removeIf(item -> item.getName().equals(nameInput()));
Remove all items that match given condition
This is not good to remove element from ArrayList. In case you know that you have to remove element from the middle of the List, do use LinkedList.
You are trying to remove an item while you are traversing/iterating the list in the for loop. You cannot remove an item from the list iterating it in a for loop. Use an Iterator instead and invoke arr.remove().
If you use Java 8 you could do
private void removeItem() {
arr.removeIf(t -> t.getName().equals(nameInput));
}
Note that this will remove all objects with name equal to nameInput
Also you should change your declaration of arr to
List<Arr> arr = new ArrayList<>();
A couple of things here...
The loop variable receiver type should ideally be Arr instead of Object as the list contains Arr objects. This also means you no longer need the cast you're performing.
You could remove the item via remove(Object o) but this requires overriding equals and hashcode based on name only. Another option is via an iterator but this would mean changing your code completely. Thus, to keep it as close to your code as possible you can use a for loop; get the index which the object is located and then remove.
Thus, you can do:
for(int i = 0; i < arr.size(); i++){
if (arr.get(i).getName().equals(nameInput)) {
Arr obj = arr.remove(i); // remove the item by index
System.out.println(obj); // print the object
break; // terminate the loop iteration
}
}

Redis with java

public void verProduto(){
//System.out.println("Digite o codigo do produto : - ");
//produt.setCodigo(scan.nextInt());
List<String> list = (List<String>) jeproduto.keys("*");
for(int i = 0; i<list.size(); i++) {
System.out.println("List of stored keys:: "+list.get(i));
}
}
This code returns error:
java.util.HashSet cannot be cast to java.util.List
Could someone help?
You havent given a lot of detail but you can try:
List<String> list = new ArrayList<String>(jeproduto.keys("*"));
Assuming you are using jedis and that the jeproduto object is a Jedis instance, per the javadocs, the keys method returns the type Set<String>
You have two options:
Change your collection type to a Set instead of a List:
Set<String> keySet = jeproduto.keys("*");
for (String key : keySet) {
System.out.println("List of stored keys: " + key);
}
Or
If you truly need a List, do what CannedMoose mentioned and take advantage of the ArrayList constructor that allows you to pass another collection.
List<String> list = new ArrayList<>(jeproduto.keys("*"));
Since your code is not fully completed.
My Assumption is
jeproduto = new HashSet<String>
then
List<String> list = (List<String>) jeproduto.keys("*"); line should be
// Creating a List of HashSet elements
List<String> list = new ArrayList<String>(hset);
if you want to convert Hashset to List, please find the sample code below.
public static void main(String[] args) {
// Create a HashSet
HashSet<String> hset = new HashSet<String>();
//add elements to HashSet
hset.add("A");
hset.add("B");
hset.add("C");
hset.add("D");
hset.add("E");
// Displaying HashSet elements
System.out.println("HashSet contains: "+ hset);
// Creating a List of HashSet elements
List<String> list = new ArrayList<String>(hset);
// Displaying ArrayList elements
System.out.println("ArrayList contains: "+ list);
}

change a list while iterating or using a for each loop

I am trying to iterate (or use a for each loop) on a Linked list class and be able to change the item (when found) to a passed in parameter.
for(Item n : items)
{
if (n.getKey().equals(key))
{
n = new Item(key, value);
}
}
Does this change of data work or is it temporary (only to be lost when the activation record is deleted)?
You can't iterate over a collection and modify it. You will always get a java.util.ConcurrentModificationException. First off all you need to use an iterator, to remove the item. Then you can use a second list to store the data you want to add.
Here you are an example:
LinkedList<String> linkedList = new LinkedList<String>();
linkedList.add("This");
linkedList.add("is");
linkedList.add("an");
linkedList.add("test");
LinkedList<String> temp = new LinkedList<String>();
for (Iterator<String> iterator = linkedList.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
if(string.equals("an")) {
iterator.remove();
temp.add("a");
}
}
linkedList.addAll(temp);
You can call iterator.remove() to savely remove the current item from list.
You are using fast enumeration, which protects the list that you are iterating through. If you would like to change the data in the list, you would need to use a traditional for loop.
Basically how fast enumeration works is it makes the array read-only in the block of code because you have no access to what integer the iteration is.
You could do this:
for(int i = 0; i < items.length; i++)
{
if (n.getKey().equals(key))
{
items[i] = new Item(key, value);
}
}

removing duplicates from list of lists and preserving lists

I have an arrayList of arrayLists. Each inner arraylist contains some objects with the format (name.version) .
{ {a.1,b.2,c.3} , {a.2,d.1,e.1} , {b.3,f.1,z.1}....}
For example a.1 implies name = a and version is 1.
So i want to eliminate duplicates in this arraylist of lists. For me , two objects are duplicate when they have the same name
So essentially my output should be
{ { a.1,b.2,c.3},{d.1,e.1} ,{f.1 ,z.1} }
Note that i want the output in the exact same form (That is , i dont want a single list with no duplicates)
Can someone provide me with an optimal solution for this?
I can loop through each inner list and place the contents in the hashset. But two issues there, i cant get back the answer in
form of list of lists.Another issue is that when i need to override equals for that object , but i am not sure if that would
break other code. These objects are meaningfully equal if their names are same (only in this case. I am not sure that would
cover the entire spectrum)
Thanks
I used Iterator.remove() to modify the collection as you move through it.
// build your example input as ArrayList<ArrayList<String>>
String[][] tmp = { { "a.1", "b.2", "c.3" }, { "a.2", "d.1", "e.1" },
{ "b.3", "f.1", "z.1" } };
List<List<String>> test = new ArrayList<List<String>>();
for (String[] array : tmp) {
test.add(new ArrayList<String>(Arrays.asList(array)));
}
// keep track of elements we've already seen
Set<String> nameCache = new HashSet<String>();
// iterate and remove if seen before
for (List<String> list : test) {
for (Iterator<String> it = list.iterator(); it.hasNext();) {
String element = it.next();
String name = element.split("\\.")[0];
if (nameCache.contains(name)) {
it.remove();
} else {
nameCache.add(name);
}
}
}
System.out.println(test);
Output
[[a.1, b.2, c.3], [d.1, e.1], [f.1, z.1]]
List<List<Pair>> inputs; // in whatever format you have them
List<List<Pair>> uniqued = new ArrayList<>(); // output to here
Set<String> seen = new HashSet<String>();
for (List<Pair> list : inputs) {
List<Pair> output = new ArrayList<>();
for (Pair p : list)
if (seen.add(p.getName()))
output.add(p);
uniqued.add(output);
}
Create a Set. Iterate over the list of lists' items. See if the item is in the Set. If it is already there, ignore it. If it isn't, add it to the Set and the list of lists.
Your method will return a new list of lists, not modify the old one. Modifying a list while iterating over it is a pain.

Categories