Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have an arraylist in java and 2 methods for it. I want to use these two methods for my arraylist at once.
In the first method, I have used the method remove(), so the arraylist doesn't have all of its elements anymore.
For the second method, I also need to have the arraylist with all of its elements. But the Arraylist is not the same anymore.
I am thinking about multithreading in java. Is there another way to solve this problem?
Here is my code:
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> list = new ArrayList<String>();
// Adding items to arrayList
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
System.out.println("The arraylist contains the following elements: " + list);
method1(list);
method2(list);
}
public static void method1(List<String> list) {
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String s = iterator.next();
if (!s.startsWith("a")) {
iterator.remove();
}
}
System.out.println("List1: " + list);
}
public static void method2(List<String> changedFilesList) {
for (Iterator<String> iterator = changedFilesList.iterator(); iterator.hasNext();) {
String s = iterator.next();
if (!s.startsWith("b")) {
iterator.remove();
}
}
System.out.println("List2:" + changedFilesList);
Output:
The arraylist contains the following elements: [aaa, bbb, ccc, ddd]
List of the other: [aaa]
List of the other: []
Expected Output:
The arraylist contains the following elements: [aaa, bbb, ccc, ddd]
List of the other: [aaa]
List of the other: [bbb]
Those two methods look too much alike, you should combine them in to one. Also, how about looking at it a different way? In stead of removing stuff from the list, add them to another.
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
System.out.println("The arraylist contains the following elements: " + list);
System.out.printLn("List 1: " + method(list, "a"));
System.out.printLn("List 2: " + method(list, "b"));
}
private List<String> method(List<String> list, String filter) {
List<String> filteredList = new ArrayList<>();
for (String s : list) {
if (s.startsWith(filter)) {
filteredList.add(s);
}
}
return filteredList;
}
Make a copy of the list before calling the first method:
List<String> list2 = new ArrayList(list);
Then, call method1 with list and method2 with list2.
As ArrayList implements Cloneable you can use the following before calling method2():
final List<String> copy = (List) list.clone();
Call method2() as follows:
method2(copy);
Try this
public static void method1(List<String> list) {
List<String> list1=new ArrayList<String>();
list1.addAll(list);
for (Iterator<String> iterator=list1.iterator();iterator.hasNext();{
String s = iterator.next();
if (!s.startsWith("a")) {
iterator.remove();
}
}
System.out.println("List1: " + list1);
}
public static void method2(List<String> changedFilesList) {
List<String> list1=new ArrayList<String>();
list1.addAll(changedFilesList);
for (Iterator<String> iterator=list1.iterator();iterator.hasNext();{
String s = iterator.next();
if (!s.startsWith("b")) {
iterator.remove();
}
}
System.out.println("List2:" + list1);
}
Related
I am trying to delete the elements from list1 that are in list1
package listCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Arry2List {
public static void main(String[] args) {
String[] s = {"INDIA" ,"JAPAN","THAILAND","MALAYSIA"};
ArrayList<String> list1= new ArrayList<String>();
String[] s1 = {"THAILAND","MALAYSIA"};
ArrayList<String> list2= new ArrayList<String>();
for(String temp : s)
{
list1.add(temp);
}
for(String temp : s1)
{
list2.add(temp);
}
//removing elements from list1 that are in list2
System.out.println("In list1 **************");
for (String t : list1)
{
System.out.println(t);
}
System.out.println("In list2 **************");
for (String t1 : list2)
{
System.out.println(t1);
}
//editlist(list1,list2);
Iterator<String> i=list1.iterator();
while( i.hasNext() )
{
if ( list2.contains( i.hasNext() ) )
{
i.remove();
}
}
System.out.println("In list1 again **************");
for(int i1 =0;i1<list1.size();i1++)
{
System.out.println(list1.get(i1));
}
}
}
Output should be INDIA,JAPAN.
List1 should contain only those elements which are not in the list2.
I am a beginner to Core Java and trying to learn collections.
In the loop that checks the element using List.contains(), you're passing a boolean (i.hasNext() returns whether the iterator has more elements) instead of the element. This causes the loop to run infinitely because you never call Iterator.next() to get the next element. You should use:
if (list2.contains(i.next())) {
instead of
if (list2.contains(i.hasNext())) {
It's better practice to also save the next element in a variable for re-usability:
while (i.hasNext()) {
String element = i.next();
if (list2.contains(element)) {
i.remove();
}
}
There is a built-in method to do that:
list1.removeAll(list2)
[EDIT]
You can create the lists easier using Arrays.asList:
List<String> list1 = new ArrayList<String>(Arrays.asList("INDIA", "JAPAN", "THAILAND", "MALAYSIA"));
List<String> list2 = Arrays.asList("THAILAND", "MALAYSIA");
list1.removeAll(list2);
[EDIT2]
The Arrays.asList produces unmodifiable list, so we have to use it to initialize a modifiable one.
[EDIT3]
Your code doesn't work because you don't advance the iterator. i.hasNext() only checks if there is a next element. It returns true or false, not the element itself. Here is how to fix this:
while (i.hasNext()) {
if (list2.contains(i.next())) {
i.remove();
}
}
You can also iterate over the list2 elements and remove them from list1:
for (String el : list2) {
list1.remove(el);
}
This question already has answers here:
Java Beginner: How do I link one linked list to another?
(6 answers)
Closed 8 years ago.
I hava list of LinkedList and I want to make (unable to modified) One connected LinkedList .
and not change the original linkedLists.
LinkedLists<String> a=new LinkedList<String>();
LinkedLists<String> b=new LinkedList<String>();
LinkedLists<String> c=new LinkedList<String>();
a.add("as");
a.add("sa");
a.add("bb");
b.add("as");
b.add("sa");
c.add("bb");
c.add("d");
c.add("ya");
the new LinkedList contain ya d bb sa as bb sa as
so I want to make one Linked List.I preffer Not copy the items casue this consume memory.
Only connect theme for go all over the items not to modified the items.
Thanks!
Try Collections#unmodifiableList()
Sample code:
LinkedList<String> a = new LinkedList<String>();
a.add("as");
a.add("sa");
a.add("bb");
a.add("as");
a.add("sa");
a.add("bb");
a.add("d");
a.add("ya");
List<String> b = Collections.unmodifiableList(a.subList(0, 3));
List<String> c = Collections.unmodifiableList(a.subList(5, 8));
b.set(0, "aa"); // not allowed
c.add("zz"); // not allowed
a.set(6, "zz"); // allowed and List c is also updated.
Try subclassing List. Here's a quick example I put together below. It's largely incomplete but you'll get the idea.
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Experiment {
public static void main(String[] args) throws Exception {
LinkedList<String> a = new LinkedList<String>();
LinkedList<String> b = new LinkedList<String>();
LinkedList<String> c = new LinkedList<String>();
a.add("as");
a.add("sa");
a.add("bb");
b.add("as");
b.add("sa");
c.add("bb");
c.add("d");
c.add("ya");
MyLinkedList<String> list = new MyLinkedList<String>();
list.add(a);
list.add(b);
list.add(c);
for (String s : list) {
System.out.println(s);
}
}
private static class MyLinkedList<T> extends LinkedList<T> {
private List<List<T>> lists = new LinkedList<List<T>>();
public void add(LinkedList<T> list) {
lists.add(list);
}
#Override
public Iterator<T> iterator() {
return new MyLinkedIterator<T>(lists);
}
}
private static class MyLinkedIterator<T> implements Iterator<T> {
private List<List<T>> lists;
private int listIndex = 0;
private int currentIndex = 0;
private T next;
public MyLinkedIterator(List<List<T>> lists) {
this.lists = lists;
}
public boolean hasNext() {
if (listIndex >= lists.size()) return false;
List<T> list = lists.get(listIndex);
if (currentIndex >= list.size()) {
currentIndex = 0;
listIndex++;
return hasNext();
}
next = list.get(currentIndex++);
return true;
}
public T next() {
return next;
}
public void remove() {
}
}
}
How about this:
LinkedList<String> a=new LinkedList<String>();
LinkedList<String> b=new LinkedList<String>();
LinkedList<String> c=new LinkedList<String>();
a.add("as");
a.add("sa");
a.add("bb");
b.add("as");
b.add("sa");
c.add("bb");
c.add("d");
c.add("ya");
LinkedList<String> unionList = new LinkedList<String>();
unionList.addAll(a);
unionList.addAll(b);
unionList.addAll(c);
LinkedList<String> unmodifiableUnion = Collections.unmodifiableList(unionList);
It uses addAll() to add all lists into a new one and returns an unmodifiable list from it using Collections.unmodifiableList()
Update
If memory consumption is your problem, the standard JDK is not enough. You will have to implement your own or use an existing one.
To implement your own you can usa a LinkedList<List<T>> to store your linked lists and implement the List interface. mprivat started an implementation for you.
To use an existing one, you could use:
Trove: it is considered really good and fast if no fastest with least memory consumption, at least that is what I have observed in my usages of it.
this implementation: it is a singly linked list so it consumes less memory and has a merge method that will merge 2 linked lists using their "pointers" as you would expect.
Apologies for the newbie question, but what's the proper way to get a Set (say LinkedHashSet) in reverse order? For Collections there's Collections.reverse(Collection c), but how does one do it for a Set with ordered elements (like a LinkedHashSet)?
Sets are not ordered in general, so to preserve the sorting, after sorting the set as a list, you would need to use a known iteration order implementation of Set, such as LinkedHashSet
List list = new ArrayList(set);
Collections.sort(list, Collections.reverseOrder());
Set resultSet = new LinkedHashSet(list);
You could also use TreeSet with a comparator, but that is not as fast as the ArrayList method above.
public class LargestArray {
public static void main(String[] args) {
ArrayList<Integer> al = new ArrayList<>();
Set<Integer> set = new TreeSet<>();
set.add(10);
set.add(20);
set.add(7);
set.add(4);
set.add(1);
set.add(2);
set.add(3);
set.add(4);
System.out.println("after Sorting");
for(int i : set) {
System.out.print(" " + i);
}
al.addAll(set);
set.clear();
Collections.reverse(al);
System.out.println();
System.out.println("After Reverse");
for (int i : al) {
System.out.print(" " + i);
}
}
}
output = after Sorting
1 2 3 4 7 10 20
After Reverse
20 10 7 4 3 2 1
Check this out
http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#descendingSet()
If you use a TreeSet you can get reverse order by calling descendingSet.
I will explain you with an example. Comments are added in mid of the code for better understanding.
public class ReverseLinkedHashSet {
public static void main(String[] args) {
// creating a LinkedHashSet object which is
// of type String or any. Will take a example of String.
HashSet<String> cars = new LinkedHashSet<String>();
// adding car elements to LinkedHashSet object as below
cars.add("Toyato");
cars.add("Hundai");
cars.add("Porshe");
cars.add("BMW");
// Iterating using enhanced for-loop to see the order.
System.out.println("Insertion Order: Iterating LinkedHashSet\n");
for(String car : cars) {
System.out.println(car);
// Output will be as below
//Toyato
//Hundai
//Porshe
//BMW
}
// Now convert to ArrayList to rearrange to reverse
// the linkedHashset
List<String> listOfCars = new ArrayList<String>(cars);
// to reverse LinkedHashSet contents
Collections.reverse(listOfCars);
// reverse order of LinkedHashSet contents
// can be done as below
System.out.println("\n\n\nReverse Order of LinkedHashSet\n");
for(String car : listOfCars) {
System.out.println(car);
// Output will be as below
//BMW
//Porshe
//Hundai
//Toyato
}
}
}
Also, I suggest not to use LinkedhashSet without a strong reason. For a complex application, it will reduce the performance. Use HashSet instead.
Java 8, I using solution below,
Set<String> setTest = new HashSet<>();
setTest.add("1");
setTest.add("2");
setTest.add("3");
List<String> list = new ArrayList<>(setTest);
list.sort(Collections.reverseOrder());
Set<String> result = new LinkedHashSet<>(list);
for (String item: result) {
System.out.println("---> " + item);
}
Result:
---> 3
---> 2
---> 1
Work for me.
public class ArrayListTest {
public static void main(String[] args) {
ArrayList al=new ArrayList();
al.add("");
al.add("name");
al.add("");
al.add("");
al.add(4, "asd");
System.out.println(al);
}
}
o/p [, name, , , asd]
desire O/p [name,asd]
You can use removeAll(Collection<?> c) :
Removes all of this collection's elements that are also contained in
the specified collection
al.removeAll(Arrays.asList(null,""));
This will remove all elements that are null or equals to "" in your List.
Output :
[name, asd]
You can remove an object by value.
while(al.remove(""));
Iterate over the list, read each value, compare it to an empty string "" and if it is that, remove it:
Iterator it = al.iterator();
while(it.hasNext()) {
//pick up the value
String value= (String)it.next();
//if it's empty string
if ("".equals(value)) {
//call remove on the iterator, it will indeed remove it
it.remove();
}
}
Another option is to call List's remove() method while there are empty strings in the list:
while(list.contains("")) {
list.remove("");
}
List<String> al=new ArrayList<String>();
...................
for(Iterator<String> it = al.iterator(); it.hasNext();) {
String elem = it.next();
if ("".equals(elem)) {
it.remove();
}
}
I do not comment this code. You should study from it yourself. Please pay attention on all details.
I have the following code sample, im pretty sure the first block should be placed in the main(), but where do I place the second block to make this Iterator example work?
List<String> myList= new ArrayList<String> ( );
Where do i place this? Would I need to create a second class?
static void printAll(ArrayList myList)
{
Iterator it = myList.iterator();
}
then there's this typical iterator pattern....is this in any way related to the second code block?
static void printAll(ArrayList myList)
{
Iterator it = myList.iterator();
Object temp;
while( it.hasNext() )
{
temp = it.next();
System.out.println( temp );
}
return;
}
It isn't clear what you want to achieve, if you are asking how to pass your ArrayList (local variable in main) to the printAll method, do something like below:
public class XYZ {
static void printAll(ArrayList myList)
{
Iterator it = myList.iterator();
Object temp;
while(it.hasNext() )
{
temp = it.next();
System.out.println( temp );
}
return;
}
public static void main(String...args){
List<String> myList= new ArrayList<String> ( );
myList.add("Hello");
myList.add("World");
printAll(myList);//passing myList to printAll
}
}
Is there a reason you're trying to use an interator?
You can do something like this, assuming you're on Java 5.
List<String> myList= new ArrayList<String> ( );
// set up list... etc.
for(String currentString : myList) {
System.out.println(currentString);
}
Iterators are only useful if you need to remove some element of the collection while traversing it (using the Iterator.remove() method). Otherwise, just use a for-each loop.