Im having a problem with my for loop for iterating over an ArrayList that hold objects. I make an ArrayList that hold these items, LumberItem is just a String for the name and an int for the amount.
ArrayList<LumberItem> lumberList = new ArrayList<LumberItem>();
LumberItem wood1 = new LumberItem("Oak", 1500);
lumberList.add(0, wood1);
LumberItem b = new LumberItem("Pine", 1500);
lumberList.add(1,b);
LumberItem c = new LumberItem("Cedar", 1500);
lumberList.add(2, c);
LumberItem d = new LumberItem("Maple", 1500);
lumberList.add(3, d);
LumberItem exp = new LumberItem("Birch", 1500);
lumberList.add(4, exp);
I try to use a for loop like so
for(int i = 0; i < lumberList.size(); i++) {
contentTA.setText(lumberList.get(i).getType());
contentTA.append("\n at index" + i + "\n");
}
My output consists of only the last element in my ArrayList so,
Birch is outputted. I have tried using different methods of looping like
for(LumberItem l : lumberList)
I am still at the end of my ArrayList when I try and output. I wondering why this is happening since I haven't figured it out.
So I'm an idiot, I was using .setText() which will clear the JTextArea every time I call it, so it should be .append()!
for(LumberItem L : lumberList) {
contentTA.append("\n" + L.getType());
}
or
for(int i = 0; i < lumberList.size(); i++) {
contentTA.append(lumberList.get(i).getType());
Will work.
Hopefully my poor reading skills help out someone else!
Related
I have a long list of lines in (possibly) random order. So basically:
struct Line
{
Vector StartPos;
Vector EndPos;
};
Now I'm looking for an efficient way to sort these lines so that they are sorted into spans. I.E. if line A's startpos matches Line B's endpos, it gets moved into the list immediately after line B. If nothing matches, it just goes to the end of the list to start a new span.
Right now I'm doing it brute force-- setting a flag variable if anything was changed, and if anything changed, sorting it again. This produces gigantically exponential iterations. Is there any faster way to optimize this so that I could conceivably keep the iterations down to listsize^listsize?
If you do not have lines that start or end at the same point maybe you can use dictionaries to reduce the look ups. Something like:
public class Line
{
public Point StartPos;
public Point EndPos;
public bool isUsed = false;
};
and then 1) create a dictionary with the key the endPos and the value the index of the element in you list, 2) for each element of the list follow the link using the dictionary. Something like:
List<List<Line>> result = new List<List<Line>>();
Dictionary<Point,int> dic= new Dictionary<Point,int>();
for (int kk = 0; kk < mylines.Count; kk++)
{
dic[mylines[kk].EndPos] = kk;
}
for (int kk = 0; kk < mylines.Count; kk++)
{
if (mylines[kk].isUsed == false)
{
var orderline= new List<Line>();
orderline.Add(mylines[kk]);
int mm = kk;
while (dic.ContainsKey(mylines[mm].EndPos))
{
mm = dic[mylines[mm].EndPos];
mylines[mm].isUsed = true;
orderline.Add(mylines[mm]);
}
result.Add(orderline);
}
}
I have a stream of numbers such as
[2872, 2997, 3121, 13055, 14178, 14302, 23134, 23382, 23507, 32832, 33677, 34017, 43415, 44246, 44374, 52866, 54035, 54158, 62835, 64243, 64936, 73110, 73890, 74014, 82809, 83771, 83899, 93436, 94765, 94891].
I would like to split it as follows:
[[2872, 2997, 3121], [13055, 14178, 14302], [23134, 23382, 23507], [32832, 33677, 34017], [43415, 44246, 44374], [52866, 54035, 54158], [62835, 64243, 64936], [73110, 73890, 74014], [82809, 83771, 83899], [93436, 94765, 94891]].
It is to be noted that the distance between the groups could be closer to each other, also the digits within a group could be farther away.
This is not an answer, but a way to look at your data, which should be insightful.
Original values:
Deltas:
Can't you just create a list of list of integers (or array of array) with size N/3 (N being the total of your numbers), and then just loop on this length and put the minimal number in it?
Something like this (I don't know what language you are using so I use c# as exemple):
int len = numbersStream.count();
List<List<int>> BigList = new List<List<int>>();
List<int> smallList = new List<int>();
for (int i = 0; i < len; ++i)
{
smallList = new List<int>();
for (int j = 0; j < 3; ++i)
{
int value = Math.Min(numbersStream);
smallList.Add(value);
numbersStream.remove(value);
}
BigList.Add(smallList);
}
BigList will be : (2872, 2997, 3121), (13055, 14178, 14302) etc...
*Assuming you always have exactly %3 numbers, otherwise you just tune the algorithm to avoid exceptions
The solution is in java but basically what this does is find the average delta and groups everything in a subset if the difference between the two elements is smaller then that average. You can fine tune this process by changing how the averageDelta operates
ps. this solution assumes your input is at least 1 large and called temp
int[] diffrence = new int[temp.length-1];
for (int i=1; i < temp.length; i++) {
diffrence[i-1] = temp[i]-temp[i-1];
}
int averageDelta = (int) Math.round(Arrays.stream(diffrence).average().orElse(1.0));
List<List<Integer>> resultList = new ArrayList<>();
List<Integer> currentList = new ArrayList<>();
currentList.add(temp[0]);
for (int i=1; i < temp.length; i++) {
if (temp[i]-temp[i-1] > averageDelta) {
resultList.add(currentList);
currentList = new ArrayList<>();
}
currentList.add(temp[i]);
}
resultList.add(currentList);
System.out.println(resultList.toString());
This is a section of my code, I have an ArrayList of 10 objects called "bob" and I want to loop through them so that each of their names (a local integer defined in the bob class) to be put in the array named "names" in order.
for (bob b : bob) {
for (int i = 0; i < 10; i++){
names[i] = b.name;
}
}
I tried this approach:
for (bob b : bob) {
for (int i = 0; i < 10; i++){
names[i] = b[i].name; //I added the "[i]" after b attempting to loop through
//the arraylist but it does not work
}
}
the syntax does not seem to allow me to loop through the arraylist of the objects like that. I am a beginning programmer so please excuse my lack of programming knowledge. It would be very helpful if someone could at least give me an idea of where to go from here. Thank you in advance!
When dealing with ArrayList you need to use the set() and get() methods to access the contents of it. Here's a somewhat hamfisted attempt at recreating the scenario you describe. Hope it helps.
class Bob {
int name;
Bob() {
this.name = floor(random(10000));
}
}
void setup(){
ArrayList<Bob> alb = new ArrayList<Bob>();
for(int i = 0; i < 50; i++){ //populate ArrayList
alb.add(new Bob());
}
int[] names = new int[10];
for(int i = 0; i < names.length; i++){
names[i] = alb.get(i).name; // use get() method
}
for(int i = 0; i < names.length; i++){
print(names[i]);
print('\n');
}
}
Your question highlights two techniques for iterating over a collection: with or without, an index. Each is best suited for different data structures and scenarios. It takes some experience to decide when to use one or the other, and is also a matter of personal style.
It is common to write code like for( int x: myInts ) and then realize you want the index of the current item, which isn't available. Or conversely, to write code like for( int i=first; i<last; i++) and then become irritated because determining first and last is tedious, or prone to bugs.
Notice your code is a double-nested loop. It says "iterate over each item in the collection Bob, and then for each one, iterate over each item in the collection of names". So if Bob had ten items, this would iterate one hundred total times, probably not what you want. You need to rewrite as a single, non-nested for loop ...
If you decide to iterate without an index, then names should be some type of list, where you can add items using append(). Consider the StringList available in Processing. Otherwise if you decide to iterate with an index, then names could be an array, although it could still be a list if it was already populated with old values which you wish to overwrite. The following shows both techniques:
void setup()
{
ArrayList<String> baseList = new ArrayList<String>(10);
for( int i=0; i<10; i++ )
baseList.add( i, Integer.toString( i + (i*10) ) );
// Approach 1: Iterate without an index,
// build a list with no initial allocation and using append()
StringList namesList = new StringList();
for( String s : baseList )
{
namesList.append( s );
println( namesList.get( namesList.size()-1 ) );
}
// Approach 2: Iterate with an index,
// build a list using preallocation and array access
String[] namesArray = new String[10];
for( int i=0; i<10; i++ )
{
namesArray[i] = baseList.get(i);
println( namesArray[i] );
}
}
here is the code for generating random numbers,but I am getting duplicate numbers,how can I overcome this.
void getnumbers()
{
Random r = new Random();
int[] trubyte = new int[4];
for (var x = 0; x < 4; ++x)
{
trubyte[x] = r.Next(1, 5);
}
b1.Content = trubyte[0];
b2.Content = trubyte[1];
b3.Content = trubyte[2];
b4.Content = trubyte[3];
}
Just get another random number if the method returns one that you already have.
void getnumbers()
{
Random r = new Random();
int num;
var trubyte = new List<int>();
for (var x = 0; x < 4; ++x)
{
do
{
num = r.Next(1, 5);
} while(trubyte.Contains(num));
trubyte[x] = num;
}
b1.Content = trubyte[0];
b2.Content = trubyte[1];
b3.Content = trubyte[2];
b4.Content = trubyte[3];
}
I'm using List instead of an array just because it offers the Contains method right away, not any other special reason.
This is not efficient if you want to generate a big list of random, unrepeated numbers (it's O(n^2) in the worst case) but for 4 numbers it's more than enough ;)
A random number generator function can return duplicates, because the output is random.
If you are using an RNG to generate numbers which must be unique, you will need to verify that they have not already been generated before using them.
Can't you use something like this [0] on Windows Mobile? It seems more practical than writing your own RNG.
0: http://msdn.microsoft.com/en-us/library/system.security.cryptography.randomnumbergenerator(v=vs.90).aspx
You have to do it by yourself, that means checking if a number was already generated.
You can do it like gjulianm said, but it is a long list of numbers, say 1000 you would be wasting a lot of time. So if you want a randomized list of 1000 you could proceed the following way
Initialize an array trubyte of size 1000 with trubyte[0]=1,trubyte[1]=2 and so on...
Initialize a variable arraysize=1000
run a loop 1000 times in which first extract a random number k btw 0-(arraysize-1). Your random number is a[k] which you can separately in a list. Now swap trubyte[k] with trubyte[arraysize]. And finally decrease the arraysize by one.
Another way, if you don't want the numbers while in the loop is just to use the changed list after the execution of loop
void getnumbers(){
Random r = new Random();
int num;
int[] trubyte = new int[1000];
int finalList[] = new int[1000]
for (int x = 0; x < 1000; ++x)
{
trubyte[x]=x+1;
}
int arraysize=1000;
for (var x = 0; x < 1000; ++x)
{
int k=r.Next(0, arraysize);
finalList[x]=trubyte[k];
trubyte[k]=trubyte[arraysize-1];
arraysize--;
}
//use the finalList
}
we can use dictionary instead of hash-set in windows phone application.
below is the code for generating distinct random numbers.
static int[] GetRandomNumbersNonrepeat(int noOfRandomNumbers, int maxValue)
{
Dictionary<int, int> randomnumbers = new Dictionary<int, int>();
while (randomnumbers.Count < maxValue)
{
Random r = new Random();
int rnum = r.Next(1, maxValue+1);
if (!randomnumbers.ContainsValue(rnum))
{
randomnumbers.Add(randomnumbers.Count + 1, rnum);
}
}
int[] rnums = randomnumbers.Values.ToArray<int>();
return rnums;
}
I really wish Processing had push and pop methods for working with Arrays, but since it does not I'm left trying to figure out the best way to remove an object at a specific position in an array. I'm sure this is as basic as it gets for many people, but I could use some help with it, and I haven't been able to figure much out by browsing the Processing reference.
I don't think it matters, but for your reference here is the code I used to add the objects initially:
Flower[] flowers = new Flower[0];
for (int i=0; i < 20; i++)
{
Flower fl = new Flower();
flowers = (Flower[]) expand(flowers, flowers.length + 1);
flowers[flowers.length - 1] = fl;
}
For the sake of this question, let's assume I want to remove an object from position 15. Thanks, guys.
You may also want to consider using ArrayList which has more methods available than a plain array.
You can remove the fifteenth element by using myArrayList.remove(14)
I made a funtion which basically switches the index to be removed to the last and then shortens it.
int[] removeByIndex(int[] array, int index) {
int index2 = array.length-1;
int old = array[index];
array[index] = array[index2];
array[index2] = old;
array = shorten(array);
return array;
}
yourarray = removeByIndex(yourarray , arrayindex);
hope this helps!
I think that your best bet is to use arraycopy. You can use the same array for src and dest. Something like the following (untested):
// move the end elements down 1
arraycopy(flowers, 16, flowers, 15, flowers.length-16);
// remove the extra copy of the last element
flowers = shorten(flowers);
String[] myArray = { "0", "1", "2", "3", "4", "5", "6"};
String[] RemoveItem(String[] arr, int n) {
if (n < arr.length-1) {
arrayCopy(subset(arr, n+1), 0, arr, n, arr.length-1-n);
}
arr = shorten(arr);
return arr;
}
I know this question was asked a long time ago however it seems a lot of people are still looking for the answer. I just wrote this. I tested it a few ways and it seems to run the way I wanted it to.
var yourArr = [1, 2, 3, 4]; // use your array here
var removeIndex = 1; // item to get rid of
var explode = function(array, index) { // create the function
var frontSet = subset(array, 0, index - 1); // get the front
var endSet = subset(array, index , array.length - 1); // get the end
yourArr = concat(frontSet, endSet); // join them
};
explode(yourArr, removeIndex); // call it on your array
That is one way. I guess you could loop through the array as well. Something like ...
var yourArr = [1, 2, 3, 4];
var removeIndex = 2;
var newArr = [];
for(var i = 0; i < yourArr.length; i++) {
if(i < removeIndex) {
append(newArr, yourArr[i]);
} else if(i > removeIndex) {
append(newArr, yourArr[i]);
}
}
yourArr = newArr;
... think that should work too. Hope this helps anybody who needs it.