I'm learning Android and Java i have created a class let's say like this
class x(){
public int a;
public string b;
}
and then i initiate a list of this class and then added values to its properties like this
public ArrayList<x> GetList(){
List<x> myList = new ArrayList<x>();
x myObject = new x();
myObject.a = 1;
myObject.b = "val1";
mylist.add(x);
y myObject = new y();
myObject.a = 2;
myObject.b = "val2";
mylist.add(y);
return myList;
}
My Question is how can i loop through what GetList() return
i have tried
ArrayList<x> list = GetList();
Iterator<x> iterator = list.iterator();
but i don't know if this is the right way of doing this, plus i don't know what to do next i have added a breakpoint on the Iterator but it seemed to be null , the list have values thought
There are two ways to do this:
A for loop
Using the iterator method.
for loop:
for(x currentX : GetList()) {
// Do something with the value
}
This is what's called a "for-each" loop, and it's probably the most common/preferred method of doing this. The syntax is:
for(ObjectType variableName : InCollection)
You could also use a standard for loop:
ArrayList<x> list = GetList();
for(int i=0; i<list.size(); i++) {
x currentX = list.get(i);
// Do something with the value
}
The syntax for this is:
for(someStartingValue; doSomethingWithStartingValue; conditionToStopLooping)
iterator method:
Iterator<x> iterator = GetList().iterator();
while(iterator.hasNext()) {
x currentX = iterator.next();
// Do something with the value
}
You can loop through your array with a for-each loop:
for (x item: GetList()) {
doSomethingWithEachValue(item);
}
I guess you can iterate through the arraylist a number of ways. One way is the iterator:-
ArrayList<String> al = new ArrayList<String>();
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
System.out.print("Original contents of al: ");
Iterator<String> itr = al.iterator();
while (itr.hasNext()) {
String element = itr.next();
System.out.print(element + " ");
}
Another way would be a loop:
for(int i = 0; i < list.size(); i++){
list[i].a = 29;
}
Hope this helps in any way.
Ref
http://www.tutorialspoint.com/java/java_using_iterator.htm
http://examples.javacodegeeks.com/core-java/util/arraylist/arraylist-in-java-example-how-to-use-arraylist/
UPDATE
I thought that I should just put this out there from research due to the comment below about performance.
The Android docs
http://developer.android.com/training/articles/perf-tips.html
states:
The enhanced for loop (also sometimes known as "for-each" loop) can be used for collections >that implement the Iterable interface and for arrays. With collections, an iterator is >allocated to make interface calls to hasNext() and next(). With an ArrayList, a hand-written >counted loop is about 3x faster (with or without JIT), but for other collections the enhanced >for loop syntax will be exactly equivalent to explicit iterator usage.
There are several alternatives for iterating through an array:
static class Foo {
int mSplat;
}
Foo[] mArray = ...
public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}
public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
}
public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}
zero() is slowest, because the JIT can't yet optimize away the cost of getting the array length once for every iteration through the
loop.
one() is faster. It pulls everything out into local variables,
avoiding the lookups. Only the array length offers a performance
benefit.
two() is fastest for devices without a JIT, and indistinguishable
from one() for devices with a JIT. It uses the enhanced for loop
syntax introduced in version 1.5 of the Java programming language.
So, you should use the enhanced for loop by default, but consider a hand-written counted loop for performance-critical ArrayList iteration. Also this is stated by Josh Bloch's Effective Java, item 46. The iterator and the index variables are both just clutter. Furthermore, they represent opportunities for error.
The preferred idiom for iterating over collections and arrays
for(Element e : elements){
doSomething(e);
}
Josh also states when you see the colon : read it as "In". The loop reads as for each element e in elements. I do not claim this work as my own even though I wish it was. If you want to learn more about efficient code then I suggest reading Josh Bloch's Effective Java.
Try the following:
class x {
public int a;
public String b;
}
private void test() {
List<x> items = getList();
for (x item: items) {
System.out.print("val: " + item.a);
}
}
private List<x> getList() {
List<x> items = new ArrayList<x>();
x oneObject = new x();
oneObject.a = 1;
oneObject.b = "val1";
items.add(oneObject);
x anotherObject = new x();
anotherObject.a = 2;
anotherObject.b = "val2";
items.add(anotherObject);
return items;
}
Related
I have an Iterator - placed somewhere in the middle of my collection.
I want to loop over the collection from there on, returning a special element if I find it.
If I reach !hasNext() then I want to start at the begining, but I want to stop if I reach the place where I started first.
The best Idea how to solve that seems currently to save the "first" (wherever the iterator pointed when I started) element and then stop if I find that one again.
And that works as long as items can occure only once in my collection (i.e. in a HasSet).
Any better ideas how to do such thing? Iterator doesn't seem to supply a pointer/number back to me that I could compare.
With Guava Iterators (Java 7):
Iterator<YourType> iterator = Iterators.concat(yourIteratorPlaceSomewhereInMiddle, Iterators.limit(yourCollection.iterator(), positionOfSomewhereInMiddle));
With Streams (Java 8):
Optional<YourType> theAnswer = IntStream.iterate(positionOfSomewhereInMiddle, pos -> ++pos)
.map(pos -> pos % sizeOfCollection)
.mapToObj(yourCollection::get)
.limit(sizeOfCollection)
.filter(element -> element is 42)
.findFirst();
If the collection is a list, then it can be done with below code
private void Object traverseList(List namesList, int startIndex ) {
int index = 0;
Iterator iterator = namesList.listIterator(startIndex);
while (iterator.hasNext() && index < namesList.size()){
Object element = iterator.next();
/*if(element.isSpecialElement()){
return element;
}
*/
index++;
System.out.println(element);
if(!iterator.hasNext()){
iterator = namesList.iterator();
}
}
}
Since you want to transverse all the elements in the list, I am making use of list size. And during iteration, if the special element is found, it can be returned.
To start to iterate a Set from a definedValue I do :
public void iterate(Set<Sample> set, Sample definedValue){
Iterator<Sample> iterator = set.iterator();
while(iterator.hasNext()){
Sample currentSample = iterator.next();
if(currentSample.equals(definedValue)){
while(iterator.hasNext()){
Sample sampleToConsider = iterator.next();
//Then do anything
}
}
}
}
The solution becomes more simple if you:
Don't use Iterator, it makes it more complicated
Use a List instead of Set as Set is ill-suited for this use case
public static void main(String[] args) {
Set<String> yourStartingCollection = new HashSet<>();
List<String> fooList = new ArrayList<>(yourStartingCollection);
Optional<String> specialElement = findSpecialElementStartingFromMiddle(fooList);
if (specialElement.isPresent()) {
// found it!
}
}
private static Optional<String> findSpecialElementStartingFromMiddle(List<String> elements) {
int middleIndex = elements.size() / 2;
Optional<String> result = Optional.empty();
for (int i = middleIndex; i < elements.size(); i++) {
String element = elements.get(i);
if (isSpecial(element)) {
result = Optional.of(element);
break;
}
}
if (result.isPresent()) {
return result;
}
for (int i = 0; i < middleIndex; i++) {
String element = elements.get(i);
if (isSpecial(element)) {
result = Optional.of(element);
break;
}
}
return result;
}
private static boolean isSpecial(String element) {
return element.equals("I'm special");
}
I've just started working with Java for a Data Strutures and Algorithms class (my background is mainly C++) and I've run into something quite clunky in my first assignment.
We were to create a "set" data structure - a bag that does not accept duplicates. From what I can tell, this is essentially just an ArrayList with some extra checks made during the add().
It all works, but I was forced to do something quite clunky when returning the set as an array:
class Set<T> implements SetInterface<T> {
// Properties
private ArrayList<T> _set = new ArrayList<T>();
// Methods
public Object[] toArray() {
return this._set.toArray();
}
}
public static void main(String[] args) {
SetInterface<Integer> mySet = new Set<Integer>();
// set is filled, other tests are performed...
Object[] myArray = mySet.toArray().clone();
for (int i = 0; i < myArray.length; i++)
System.out.print((int)myArray[i] + " ");
}
I originally tried to return an array of type T[] but that threw ClassCastException:
public T[] toArray() {
#SuppressWarnings("unchecked")
T[] temp = (T[])new Object[this._set.size()];
temp = this._set.toArray(temp);
return temp;
}
public static void main(String[] args) {
SetInterface<Integer> mySet = new Set<Integer>();
// set is filled, other tests are performed...
Integer[] myArray = mySet.toArray().clone();
for (int i = 0; i < myArray.length; i++)
System.out.print(myArray[i] + " ");
}
Now, my solution up top works, but it just... feels wrong. Is there a more elegant way to accomplish this? That is, is there a way to avoid having to cast each element in the array after the fact?
Hope this is clear.
Below is the current code which works fine
Set<Employee> employeeSet = inCompanyBean.getEmployees();
Set<Employee> innerEmployeeSet = employeeSet;
Iterator<Employee> iter = employeeSet.iterator();
while (iter.hasNext()) {
Employee formerEmp = iter.next();
Iterator<Employee> itLater = innerEmployeeSet.iterator();
while(itLater.hasNext()){
Employee laterEmployee = itLater.next();
// do the processing
}
}
}
Basically want to compare values from each object with remaining objects.
Example,
If 5 Employee objects are there, comparison will be as follows
1st object - compare with all the objects values
2nd objects - compare with all the objects values
3rd object - compare with all the objects values
The above logic works fine.
However i would like to know the best way to achieve the performance. The above takes a huge amount of memory.
Thanks.
Just try converting set to list and iterate based on index like:
Set<Employee> empSet= new HashSet<Employee>();
empSet.add(...);
List<Employee> empList= new ArrayList<Employee>(empSet);
for (int i =0;i<empList.size(); i++) {
for (int j =0;j<empList.size(); j++) {
if (i==j) {
continue;
}
if (empList.get(i).compareTo(empList.get(j)) > 0) {//do something
}
}
}
The nested loop itself doesn't appear to be intrinsically memory hungry - perhaps it's just the unshown code that's consuming memory?
That said, why not use the modern for syntax and make your code massively more readable:
Set<Employee> employeeSet = inCompanyBean.getEmployees();
for (Employee outer : employeeSet) {
for (Employee inner : employeeSet) {
if (inner == outer) continue;
// do the processing
}
}
Alternatively, if proc(a, b) gives the same result as proc(b, a) and proc(a, a) is a no-op then you can half the number of processing operations by only having the inner loop iterate from one more than the outer loop's current position, which unfortunately isn't possible without using explicit indices:
Set<Employee> employeeSet = inCompanyBean.getEmployees();
Employee[] employees = employeeSet.toArray(new Employee[0]);
int n = employees.length;
for (int i = 0; i < n; ++i) {
Employee outer = employees[i];
for (int j = i + 1; j < n; ++j) { // note start value of 'j'
Employee inner = employees[j];
// do the processing
}
}
I just want ask, is it possible to initiliaze more objects with same constructor in one command?
Example of code:
Tile[] tiles = new Tile(5,5)[20];
Thanks for response.
Impossible as far as I know.
The code Tile[] tiles = new Tile[20]; just creates an array of references. To fill the array, you should create a Tile object and then assign the reference to one index of the array, such as:
tiles[0] = new Tile(5,5);
If all elements of the array pointing to the same object is OK, you can full fill the array simply use:
Tile tiles = new Tile[20];
Arrays.fill(tiles, new Tile(5,5));
No, you have to use a loop.
Tile[] tiles = new Tile[20];
for(int i = 0; i < tiles.length; i++) {
tiles[i] = new Tile(5, 5);
}
However, it is nice that in Java 8 we will be able to shorten this using the new Supplier class and a helper method.
static <E> E[] fill(E[] arr, Supplier<? extends E> supp) {
for(int i = 0; i < arr.length; i++) {
arr[i] = supp.get();
}
return arr;
}
We can then do the following:
Tile[] tiles = fill(new Tile[20], () -> new Tile(5, 5));
I think that's sort of nifty.
There's also a couple ways to do this without Java 8 by using reflection. Here's a way you can do it if the class has a copy constructor (a constructor that takes an object of its own class as an argument):
static <E> E[] duplicate(E[] arr, E element) {
#SuppressWarnings("unchecked")
Class<? extends E> cls = (Class<? extends E>)element.getClass();
try {
Constructor<? extends E> ctor = cls.getConstructor(cls);
for(int i = 0; i < arr.length; i++) {
arr[i] = ctor.newInstance(element);
}
} catch(Exception e) {
e.printStackTrace(System.err);
}
return arr;
}
So for example:
String[] arr = fill(new String[5], "Hello world!");
Reflection is a bit more unstable than the lambda, especially when dealing with subtypes and primitives. The lambda is great.
First, it is even not possible to initialize an object array with non-null value in one line (ok, except using {...} or filling them with same reference but I think it is not what you want)
You gotta create instance of array first, and fill individual element in the array:
e.g.
Foo[] myArray =new Foo[10];
for (int i = 0; i < myArray.length; ++i) {
myArray = new Foo();
}
If you are just looking for shorter code that you don't want to write the loop again and again, here is one option for you:
write a little util like this:
public class ArrayUtil {
public static T[] fillArray(T[] array, ArrayElementFactory elementFactory) {
for (int i = 0; i< array.length; ++i) {
array[i] = elementFactory.create(i);
}
return array;
}
}
public interface ArrayElementFactory<T> {
T create(int i);
}
The way to use is something like
Foo[] fooArray = fillArray(new Foo[10], new ArrayElementFactory<Foo>() {
Foo create(int i) { return new Foo(10,10); }};
If you are using Java8, I believe (haven't tried) you can use lambda expression which give you something like
Foo[] fooArray = fillArray(new Foo[10], i -> new Foo(10,10));
I have a list with 70 elements.
For Example:
List<Long> dbList = new ArrayList<Long>();
dbList has 70 records. If I send all the records to a query in MySql it takes a long time. So now I want to send each time 10 elements to database query. So I need to iterate over the list in intervals of 10. How can I do this? Is this a good approach to avoid long time when using IN.
SQL Query
select model.boothId, model.panchayat.panchayatId
from Table1 model
where model.panchayat.panchayatId in(:locationValues)
and model.publicationDate.publicationDateId in (:publicationDateIdsList)
and model.constituency.id = :id group by model.panchayat.panchayatId
Thanks in advance...
ArrayList#subList is a very efficient operation. You can iterate over ranges of size 10:
for (int i = 0; i < dbList.size(); i += 10) {
List<Long> sub = dbList.subList(i, Math.min(dbList.size(),i+10)));
... query ...
}
If you use Eclipse Collections (formerly GS Collections) and change dbList to a MutableList or something similar, you can write:
MutableList<Long> dbList = ...;
RichIterable<RichIterable<Long>> chunks = dbList.chunk(10);
If you can't change the return type of dbList, you can wrap it in a ListAdapter.
RichIterable<RichIterable<Long>> chunks = ListAdapter.adapt(dbList).chunk(10);
Note: I am a committer for Eclipse Collections.
You can use the subList method in the List interface to divide your list.
I don't know exactly what are you trying to do, but you could try something like the following pseudocode, if you build your query with a loop anyway:
counter=0;
for (Long item : dbList){
query.add (item);
if (counter>10){
query.send();
counter=0;
}
}
if (!query.empty())
query.send();
This is just pseudocode. Probably you don't have a query object like this, but is just to explain my point.
Hope it helps
In pure Java code it could be probably done:
int parts = list.size()/10;
for(int i=0; i<10; i++){
for(int j=0; j<parts; j++){
Long l = list.get(j + i*j);
// l do sth;
}
}
As d'alar'cop stated, I think it may be an issue with your SQL statement, rather than the list. But anyway, I would do something like this:
int i = 1;
List<Long> newList = new ArrayList<Long>();
for(Long item : dbList)
{
for (i <= 10; i++)
{
newList.Add(item)
if (i == 10)
{
//SQL Statement
i = 1;
}
break;
}
}
Or, a subList as the others have mentioned would work as well, and may be a more compact solution.
Simple Class which contains function to return 10 elements from list which having a start index.
import java.util.ArrayList;
import java.util.List;
public class TestTenElement {
public static void main(String[] args) {
// Getting all the element list from DB -- Here Creating Sample List
List<Long> myList = new ArrayList<Long>();
// Dummy element list
for (long i = 0; i < 51; i++) {
myList.add(i);
}
// Calling function may be from different class
System.out.println(getFiveElement(myList, 0)); // First Ten Element from StartIndex 0
System.out.println(getFiveElement(myList, 10)); // Second Ten Element from StartIndex 5
// .......
System.out.println(getFiveElement(myList, 50)); // If Last Iteration Gives remaining elements
}
// print ten element from list from the start index specified
public static List<Long> getFiveElement(List<Long> myList, int startIndex) {
List<Long> sub = new ArrayList<Long>();
sub = myList.subList(startIndex, Math.min(myList.size(), startIndex + 10));
return sub;
}
}
Below code snippet might be helpful.
int pointer =0;
List<Long> chunks = null;
List<Long> longValues = LongStream.rangeClosed(1, 100).boxed().collect(Collectors.toList());
int limit =10;
do{
chunks = new ArrayList<>();
for(int incrementor =pointer ; incrementor < longValues.size() && incrementor < pointer+limit; incrementor++){
chunks.add(longValues.get(incrementor));
}
if(chunks.size() == limit){
pointer = pointer + limit;
}
if(chunks.size() >0){
System.out.println(chunks);
//your update query goes here
}
}while(chunks.size() ==limit);