creating an array from another array using a loop - java

I am Passing an Array into a for loop with an if statment, I am want to have all the elements that evaluate true be added to a new array. How Do I do This?

Supposing you have an object array, and you want to create a possibly smaller array containing the elements that satisfy some predicate, you are faced with the problem of knowing how big to make the new array. You can determine that only by testing each starting element against the predicate, which you would normally prefer to avoid doing twice. One way to approach the problem would be to use a List to temporarily hold the elements you want to collect:
MyElementType[] myArray = { /* ... */ };
MyElementType[] result;
List<MyElementType> temp = new ArrayList<MyElementType>();
for (MyElementType element : myArray) {
if (passesMyTest(element)) {
temp.add(element);
}
}
result = temp.toArray(new MyElementType[0]);
Of course, it's usually easier to work directly with Lists instead of with arrays, but sometimes you don't have that luxury.

Related

How to return an array from a list [Java]

Here is how my code is set up:
public String[] function(List<String[]> playerList){
i = 5
return playerList[i];
When I try to run this code, I get the error:
Array type expected; found: 'java.util.List<java.lang.String[]>'
I know I'm screwing something up by mixing my arrays and lists, what would be the right way of fixing this code, assuming I can't change my list input to an array?
You access an element at an index in a List with a call to List.get(int index) (not [], that is accessing an element in an array). Like,
return playerList.get(i);
not like c++, which can do operator overloading.
in java, playerList is a list, you cannot apply "[]" to it, but the list's element/item is an Array type (String[]). so, you should use list.get() and with it's element, you could use [] operator: (playerList.get(i))[0]
playerList is List type, for accessing element in the List you must call get function.
for example >> playerList.get(0) , then you will get element's value in index-0. In this case, you will return String of Array. And if you want accessing that Array element, you can use playerList.get(0)[i]
So, you were trying to get an array of strings however, there could be two (2) things you wanted to take a look. First, you might want to specify playerList as an ArrayList<String> and then(second), you are trying to return playerList[i] as string and not as an array of string as specified String[].
public String[] function(List<String[]> playerList){
i = 5
return playerList[i];
You might want to try this instead?
return playerList.toArray(new String[playerList.size()]);

Variable length objects and using traditional for loop

In one of my methods, I need to pass objects as variable length parameters.
However, first I need to process the last object and then based on that many other processing will be done. I could not figure out how to use the index for each of the items in the variable argument list using traditional for loop and then index. So I used below code. Is this the right method to copy the object reference to another Array or ArrayList as I did? Otherwise what is the best method to access the specific object first and then loop through all other objects.
public static int generateConnectedPatterns(String endStr,Moorchana.MoorchanInnerClass...totalPatterns) {
// First copy all the objects to new ArrayList or Array of objects
ArrayList <Moorchana.MoorchanInnerClass> objectList = new ArrayList<>();
objectList.addAll(Arrays.asList(totalPatterns));
//Temporarily use lastObject variable for convenience.
Moorchana.MoorchanInnerClass lastObject = objectList.get(objectList.size()-1);
// Split the last input string into swaras
ArrayList<Integer> indices = new ArrayList<>();
ArrayList<String> tempPatternList = new ArrayList<>();
splitInputPatternIntoArrayList(tempPatternList , indices, lastObject.rawInputString);
if (Moorchana.validatePresenceInSwaraPool(endStr, lastObject.returnOuterObjectRef().swaraPool) == -1) {
return (-1);
}
// Get the index of the ending String
int indexofEndStr = lastObject.returnOuterObjectRef().getSwaraIndex(endStr);
// Now get the number of patterns to be generated.
int count = lastObject.returnOuterObjectRef().getPatternCount(indices, indexofEndStr);
// Now Do remaining programming here based on the count.
return(Constants.SUCCESS);
}
A varargs is basically an array.
Once you checked for null and length, you can access the last element just as you would with an array.
On the other hand, Arrays.asList returns a fixed-size list, which means you will not be able to manipulate its size later on, so beware of UnsupportedOperationExceptions.
In short, you can use the varargs as array and reference the last element once the necessary checks are performed.
Treat totalPatterns as an array.
To identify the last element: totalPatterns[totalPatterns.length-1]
for iteration, you could use an enhanced for loop.
for ( Moorchana.MoorchanInnerClass d : totalPatterns){...}
Note: Do a null check before you process the array, if you are not sure of the input being passed.

Shorter way to compare two lists and remove values that are in both?

I'm trying to compare two ArrayLists and remove values from a list if they appear on a second one. Both lists contain the same class: "EditableListItem.
ArrayList<EditableListItem> items = new ArrayList<EditableListItem>();
ArrayList<EditableListItem> addedItems = new ArrayList<EditableListItem>();
I have written this code, which does the job however I don't feel it's a very good solution.
int remove_n = -1;
for(int k=0;k<addedItems.size();k++)
{
for(int i=0;i<items.size();i++)
{
if(items.get(i).getKey().equals(addedItems.get(k).getKey()))
{
remove_n = i;
}
}
if(remove_n > -1)
{
items.remove(remove_n);
remove_n = -1;
}
}
Is there a way to do this with less lines? Or maybe using some method from ArrayList?
Thanks
You can use ArrayList#removeAll(Collection c), e.g. items.removeAll(addedItems).
If you want it to run faster, make a HashSet from one collection, then call its removeAll() method.
To remove all items from a collection that are in another collection, use removeAll.
items.removeAll(addedItems);
You could note down all the array indices (in both arrays) where array elements are the same, and one you iterate thrrough both lists, remove the common elements using
items.remove(index);
method.
Don't remove without iterating completely through both the arraylists, because when you remove one element, the array indices for all subsequent elements change.
Else, if you would like to do it in one loop itself, as and when you delete the element, decrement your loop variable by one, so that index associativity is maintained for both arraylists.

Is it possible to use the values method for a HashMap if the values are ArrayLists?

I'm stuck trying to get something to work in an assignment. I have a HashMap<Integer, ArrayList<Object>> called sharedLocks and I want to check whether a certain value can be found in any ArrayList in the HashMap.
The following code obviously wouldn't work because Object[] can't be cast to ArrayList[], but it is a demonstration of the general functionality that I want.
ArrayList[] values = (ArrayList[]) sharedLocks.values().toArray();
boolean valueExists = false;
for (int i = 0; i < values.length; i++) {
if (values[i].contains(accessedObject)) {
valueExists = true;
}
}
Is there a way for me to check every ArrayList in the HashMap for a certain value? I'm not sure how to use the values method for HashMaps in this case.
Any help would be much appreciated.
HashMap.values() returns a Collection. You can iterate through the collection without having to convert it to an array (or list).
for (ArrayList<Object> value : sharedLocks.values()) {
...
}
A HashMap is a bit special, in that it doesn't really have an index to go by at all...
What you want to do, is turn the HashMap into a collection first, and then iterate through the collection with an iterator.
Whenever you get hold of an ArrayList in the HashMap, you cycle through every element in the arrayList, and then you jump out if you find it :)
Use the toArray method which takes an array as an argument.
This uses the array you specify to fill the data, and maintains the typing so you don't need to typecast. Additionally, you should keep the generic <Object> in the definition.
ArrayList<Object>[] values =
sharedLocks.values().toArray(new ArrayList<Object>[sharedLocks.size()]);
One more thing to consider is if multiple threads can modify this HashMap. In this case, you will want to synchronize this line of code to the HashMap and make sure all modifications are also synchronized. This will make sure that other threads won't modify the contents between the .size() call and the .toArray() call, which is possible.
You dont need arrays:
boolean valueExists = false;
for (ArrayList<Object> value : sharedLocks.values()) {
if (value.contains(accessedObject)) {
valueExists = true;
break;
}
}
Why not just iterate through all the values in the map:
for (ArrayList<Object> list : sharedLocks) {
if (list.contains(accessedObject)) {
// ...
}
}
heres a link to an example of iterating though a hash map. Use this to pull out each arraylist and in turn extend this to then search each element of the array list for the given entry.
http://www.java-examples.com/iterate-through-values-java-hashmap-example
you will need to use a nested foreach loop.
foreach(every element in the hashmap) {
foreach(every element in arraylist) {
// do comparision
}
}
you might just get away with a foreach loop and a keyExists() call or something within it. I cannot recall the API off the top of my head.

ArrayList with returned index on add value

I am looking for a java data structure similar to an ArrayList that when I do an add or a push with only a value argument an index will be returned for me automatically.
For example:
ArrayList<String> elements = new ArrayList<String>();
String element = "foo";
String elementTwo = "bar";
int index1 = elements.add(element); //note this does not exist, i.e. returns bool in api
int index2 = elements.add(elementTwo);
System.out.println(elements.get(index1)); //would give "foo"
I could see writing a wrapper class around ArrayList that manages a counter that is incremented on every add operation and invoking:
ArrayList.add(int index, E element)
Do you really need to write a wrapper around ArrayList for this? This seems like something simple enough to be provided out of the box somewhere?
Edit:
I need the index (key) to be fixed and unique for this usecase. A map was suggested and I agree with that. Does anyone know of a map implementation that gives you an automatically (uniquely) generated key on a value insert? I am just trying to decide if I need to implement my own wrapper for this.
The element will be added at the end of the list. So you can use elements.size()-1 to get the new elements index.
Note that this will not work reliable if multiple threads are modifying the list at the same time.
EDIT: Also note that it might not be a good idea to use an ArrayLists index as a unique ID because an elements index can change (for example when you remove an element or insert a new one using add(int, Object)). If this is a problem depends on what you want to do with the index: If you only need it for a short time after adding an element and can be sure that the list is not modified in the meantime, there is no problem. In the other case even a method returning the index when calling add(Object) would not help because the index does not get updated in anyway. To prevent this issue you can:
Make sure you never remove elements from the list and never add elements using add(int, Object).
Instead of removing elements you could also set them to null using the method set(int, null). This way no elements index will change.
Use some other data structure like for example a map with a custom ID like helloannalil suggests in his answer.
EDIT 2: I did not find a appropriate, ready to use implementation (but this does not mean there is none, of course). To suggest a good solution, more information on the intended use of the data structure is needed, but here are some ideas and notes:
If the maximum number of elements is not to large, an ArrayList could be used and the elements index represents the ID. As stated above, to remove an element it can be set to null so that no indices are changed. When inserting, positions with null values can be reused.
You can also use one of the two methods show in this answer: https://stackoverflow.com/a/8939049/1347968 (keywords AtomicLong or IdentityHashMap)
Do not depend on the "uniqueness" of Object.hashCode() or System.identityHashCode(Object) as it is not guaranteed (try it by running the example at the bottom of Suns/Oracles Bug #6321873).
Well what I do in that cases (I love ArrayLists) is to get the last index by asking the size of the list:
String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;
I mean, is easier than implement your own List and just works.
if you really want this function, you can use map but not list
Based on your comments and edited question I think you can extend a HashMap for your use like this:
public class MyMap<V> extends HashMap<Integer, V> {
private static final long serialVersionUID = 1L;
public int add(V elem) {
int key = System.identityHashCode(elem);
super.put(key, elem);
return key;
}
}
Then inside your class declare MyMap like this:
private MyMap<String> map = new MyMap<String>();
And then add your elements to MyMap like this:
.....
.....
String element = "foo";
String elementTwo = "bar";
int index1 = map.add(element);
int index2 = map.add(elementTwo);
Now you have index1 and index2 as indices of you inserted strings that you can use or pass around for the lifetime of your application. You can insert or remove elements in MyMap as many times you want but your indices (index1 and index2) will give you back your inserted elements like this:
String elem1 = map.get(index1); // will return "foo"
String elem2 = map.get(index2); // will return "bar"
String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;
If you remove an item, this will no longer work.

Categories