I'm a beginner in Java and a geomatics student.
I work with an XTF image, its works like TIFF. This image store about 20000 lines called pings with several informations : coordinates, start time, stop time... The treatments I use on Intellij become too heavy but it works well.
I want to cut in two the informations stored in my XTF image :
1 image with the 10000 first pings and the other with the 20000 last pings. Later I would gather the two images.
My question is simple : how, with a “for each” loop can I order a limit (<=10000) ? I stored the information in a csv file.
for (XtfPing ping : xtf.getPings())
{
writer.write( Double.toString( ping.x) );
writer.write( "," );
writer.write( Double.toString( ping.y) );
writer.write( "\n" );
}
writer.close();
I know this doesn't fit exactly the OP's situation, but maybe this will help someone else looking to implement an iterate limit using Java 8:
List<Object> myList = ...
List<Object> first10000 = myList.stream().limit(10000).collect(Collectors.toList());
for (Object obj : first10000) {
// do stuff
}
or more simply:
List<Object> myList = ...
myList.stream().limit(1000).forEach(o -> {
// do stuff
});
If you must you an enhanced for loop, you must introduce your own counter in order to test the number of iterations :
int limit = 0;
for (XtfPing ping : xtf.getPings())
{
if (limit <= 10000) {
// do something
} else {
// do something else
}
limit++;
}
An alternative (if getPings() returns a Collection that supports random access (such as List) or an array) is to replace your enhanced for loop with a traditional for loop, in which the iteration number is built in.
For example, if getPings returns a List :
for (int i = 0; i < xtf.getPings().size(); i++)
{
XtfPing ping = xtf.getPings().get(i);
if (i <= 10000) {
// do something
} else {
// do something else
}
}
You can use an int to increment every loop and a break; to stop the for loop
int i = 0;
for (XtfPing ping : xtf.getPings()) {
(if i <= amountOfLoops) {
writer.write( Double.toString( ping.x) );
writer.write( "," );
writer.write( Double.toString( ping.y) );
writer.write( "\n" );
} else {break;}
}
writer.close();
Related
I am passing some parameters in the URL and then I add them in a list. My list has a limit of 5 elements. So if someone adds 6th element in the URL the list would simply ignore it. So I am trying to use a counter but the logic is not working as desired. I am using While loop to achieve this. So if list size is smaller than 5 set the agencyCds otherwise just return the list.
private List<IUiIntegrationDto> generateViewIntegrationReportData(ESignatureIntegrationConfig eSignConfig) throws Exception {
int counter = 1;
if(eSignConfig.getAdditionalAgencyCds() != null ) {
List<String> combinedAgencyCds = new ArrayList<String>();
for(String agencyCd : eSignConfig.getAgencyCd()) {
combinedAgencyCds.add(agencyCd);
}
StringTokenizer token = new StringTokenizer(eSignConfig.getAdditionalAgencyCds().toString(), StringConstants.COMMA);
while(token.hasMoreTokens()) {
combinedAgencyCds.add(token.nextToken());
}
while(combinedAgencyCds.size() < 5) {
counter = counter + 1;
eSignConfig.setAgencyCd(combinedAgencyCds);
}
// eSignConfig.setAgencyCd(combinedAgencyCds);
}
List<IUiIntegrationDto> intgList = getUiIntegrationManager().retrieveUiIntegrationReportData(eSignConfig.getAgencyCd(), eSignConfig.getCreatedDays(),
eSignConfig.getLob(), eSignConfig.getTransactionStatus(), eSignConfig.getAccounts(), eSignConfig.getSortKey(), eSignConfig.getSortOrder());
return intgList;
}
I am not completely sure about this logic if it is correct or if there is nay better approach.
Thanks
Try this instead of the last while in your code:
if(combinedAgencyCds.size() <= 5) {
eSignConfig.setAgencyCd(combinedAgencyCds);
} else {
eSignConfig.setAgencyCd(combinedAgencyCds.subList(0, 5));
}
The full combined list will then be used if it is less than 5 in size. Otherwise, only the first 5 elements are used.
Edit: Or even better:
eSignConfig.setAgencyCd(combinedAgencyCds.subList(0, Math.min(5, combinedAgencyCds.size())));
Ok so let's break down what your code is currently doing.
int counter = 1;
while(combinedAgencyCds.size() < 5) {
counter = counter + 1;
eSignConfig.setAgencyCd(combinedAgencyCds);
}
This snippet of code has a couple things wrong best I can tell. First, this loop has the possibility of running forever or not at all. Because combinedAgencyCds is never being manipulated, the size won't ever change and the logic being checked in the while loop never does anything. Second, there's a more efficient loop for doing this, assuming you don't need the counter variable outside of its usage in the while loop and that is using for loops.
Example syntax is as follows:
for (int i = 0; i < combinedAgencyCds.size(); i++) {
if (i < 5) {
// Do your logic here.
}
else {
break; // Or handle extra values however you want.
}
}
Notice there is no need for the explicit declaration for a counter variable as "i" counts for you.
Now in your actual logic in the loop, I'm not sure what the setAgencyCd method does, but if it simply sets a list variable in the eSignConfig like it appears to, repeating it over and over isn't going to do anything. From what I can see in your code, you are setting a variable with the same value 5 times. If you need any more explanation just let me know and I will be happy to revise the answer.
I need to create a method which checks each element in my array to see if it is true or false, each element holds several values such as mass, formula, area etc for one compound, and in total there are 30 compounds (so the array has 30 elements). I need an algorithm to ask if mass < 50 and area > 5 = true .
My properties class looks like:
public void addProperty (Properties pro )
{
if (listSize >=listlength)
{
listlength = 2 * listlength;
TheProperties [] newList = new TheProperties [listlength];
System.arraycopy (proList, 0, newList, 0, proList.length);
proList = newList;
}
//add new property object in the next position
proList[listSize] = pro;
listSize++;
}
public int getSize()
{
return listSize;
}
//returns properties at a paticular position in list numbered from 0
public TheProperties getProperties (int pos)
{
return proList[pos];
}
}
and after using my getters/setters from TheProperties I put all the information in the array using the following;
TheProperties tp = new properties();
string i = tp.getMass();
String y = tp.getArea();
//etc
theList.addProperty(tp);
I then used the following to save an output of the file;
StringBuilder builder = new StringBuilder();
for (int i=0; i<theList.getSize(); i++)
{
if(theList.getProperties(i).getFormatted() != null)
{
builder.append(theList.getProperties(i).getFormatted());
builder.append("\n");
}
}
SaveFile sf = new SaveFile(this, builder.toString());
I just cant work out how to interrogate each compound individually for whether they reach the value or not, reading a file in and having a value for each one which then gets saved has worked, and I can write an if statement for the requirements to check against, but how to actually check the elements for each compound match the requirements? I am trying to word this best I can, I am still working on my fairly poor java skills.
Not entirely sure what you are after, I found your description quite hard to understand, but if you want to see if the mass is less than 50 and the area is greater than 5, a simple if statement, like so, will do.
if (tp.getMass() < 50 && tp.getArea() > 5) {}
Although, you will again, have to instantiate tp and ensure it has been given its attributes through some sort of constructor.
Lots of ways to do this, which makes it hard to answer.
You could check at creation time, and just not even add the invalid ones to the list. That would mean you only have to loop once.
If you just want to save the output to the file, and not do anything else, I suggest you combine the reading and writing into one function.
Open up the read and the write file
while(read from file){
check value is ok
write to file
}
close both files
The advantage of doing it this way are:
You only loop through once, not three times, so it is faster
You never have to store the whole list in memory, so you can handle really large files, with thousands of elements.
In case the requirements changes, you can write method that uses Predicate<T>, which is a FunctionalInterface designed for such cases (functionalInterfaces was introduced in Java 8):
// check each element of the list by custom condition (predicate)
public static void checkProperties(TheList list, Predicate<TheProperties> criteria) {
for (int i=0; i < list.getSize(); i++) {
TheProperties tp = list.get(i);
if (!criteria.apply(tp)) {
throw new IllegalArgumentException(
"TheProperty at index " + i + " does not meet the specified criteria");
}
}
}
If you want to check if mass < 50 and area > 5, you would write:
checkProperties(theList, new Predicate<TheProperties> () {
#Override
public boolean apply(TheProperties tp) {
return tp.getMass() < 50 && tp.getArea() > 5;
}
}
This can be shortened by using lambda expression:
checkProperties(theList, (TheProperties tp) -> {
return tp.getMass() < 50 && tp.getArea() > 5;
});
I am using the MASON library to run a simple agent-based model.
As per specifications, I meant to access an agent's inspector by double-clicking on such agent in the Portrayal.
However, when I do so I get the following console error:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at sim.display.Display2D.createInspectors(Display2D.java:1737)
at sim.display.Display2D$8.mouseClicked(Display2D.java:1392)
I went to Display2D.java:1737 to find:
public void createInspectors( final Rectangle2D.Double rect, final GUIState simulation )
{
Bag inspectors = new Bag();
Bag names = new Bag();
Bag[] hitObjects = objectsHitBy(rect);
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
simulation.controller.setInspectors(inspectors,names); //1737
}
However, this is a library file so I'm not familiar with it.
Any advice?
Library: cs.gmu.edu/~eclab/projects/mason/
Update:
Ok, it gets interesting...
I did an echo on the toString method of inspectors and names, returning:
insepectors sim.util.Bag#1b2202a names sim.util.Bag#16b334d
Ok so they're bags, a type of collection. Time to get their sizes...
insepectors 1 names 1
Good, they're not empty.
Let's follow the error stack
Next bit:
at sim.display.Display2D$8.mouseClicked(Display2D.java:1392)
// add mouse listener for the inspectors
insideDisplay.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (handleMouseEvent(e)) { repaint(); return; }
else
{
// we only care about mouse button 1. Perhaps in the future we may eliminate some key modifiers as well
int modifiers = e.getModifiers();
if ((modifiers & e.BUTTON1_MASK) == e.BUTTON1_MASK)
{
final Point point = e.getPoint();
if( e.getClickCount() == 2 )
1392-> createInspectors( new Rectangle2D.Double( point.x, point.y, 1, 1 ),
Display2D.this.simulation );
if (e.getClickCount() == 1 || e.getClickCount() == 2) // in both situations
performSelection( new Rectangle2D.Double( point.x, point.y, 1, 1 ));
repaint();
}
}
}
Ok, the error is clearly in the CreateInspectors method:
public void createInspectors( final Rectangle2D.Double rect, final GUIState simulation )
{
Bag inspectors = new Bag();
Bag names = new Bag();
Bag[] hitObjects = objectsHitBy(rect);
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
System.out.println("insepectors " + inspectors.size() + " names " + names.size());
simulation.controller.setInspectors(inspectors,names);
}
First thing I do:
System.out.println(rect.getCenterX() + " " + rect.getCenterY());
Which gives me 646.5 659.5. Seem to make sense as coordinates.
So next thing I want to look at hitObjects:
System.out.println(hitObjects.length);
Returns 2. So I had two agents at that coordinates.
I assume the NPE is somewhere here:
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
The outer loop looks fine, but I'm having issues with the inner one. Advice?
I'm actually going to write how to reason through the library code given as far as you've come since you sound capable.
You found the code. That's a good start. You've also found the line that it's on:
simulation.controller.setInspectors(inspectors,names); //1737
And given what you know about NPEs you can reason that simulation or controller is null.
Do you know which? Can you reason about your code which you may have failed to set, or passed incorrectly? Can you put a debugger breakpoint or simple println statements in your code to determine which?
If not and you're using an IDE (you probably are), then from the source you just opened up, put a breakpoint before line 1737. When that line is reached, use the debugger to inspect the variable simulation then simulation.controller to see which is null. Exactly how to do this will depend on your IDE but it shouldn't be hard to find using XKCD's tech support cheat sheet.
Then you will probably know the cause. If not, continue reading source code, e.g. look a level up to line 1737.
I am trying to use an iterator on an ArrayList ( to get rid of a for loop, don't ask me why... ), however I need to skip the process of one of the arrays upon a boolean condition , should I still use an index and a break ???
// INTERPOLATION
int i = 0;
Iterator<CircularFifoQueue<SensorEvent>> buf = samplingFifoQueues.iterator();
while (buf.hasNext()) {
if ( i == 2 && !mDeviceSensorGyro) { // skip this queue if no gyroscope in device
break;
}
// proceed
buf.next();
i++;
}
thanks for help
What about this:
// INTERPOLATION
int i = 0;
Iterator<CircularFifoQueue<SensorEvent>> buf = samplingFifoQueues.iterator();
while (buf.hasNext()) {
if ( i != 2 || mDeviceSensorGyro) { // skip this queue if no gyroscope in device
// proceed
}
buf.next();
i++;
}
But I would rather attach some attribute to the queue elements to check for it. Work directly with numbers is bad practice.
Hello guys I'am beginner of the Java and i've got some problems with array&arraylist. My main problem is how to write computing, dynamic data into the array and later how to read it? Here's my weird code:
public static void main(String[] args) {
int yil, bolum = 0, kalan;
Scanner klavye = new Scanner(System.in);
ArrayList liste = new ArrayList();
//or shall i use this? >> int[] liste = new int[10];
System.out.println("Yıl Girin: "); // enter the 1453
yil = klavye.nextInt();
do{ // process makes 1453 separate then write in the array or arraylist. [1, 4, 5, 3]
kalan = yil % 10;
liste.add(kalan); //my problem starts in here. How can i add "kalan" into the "liste".
bolum = yil / 10;
yil = bolum;
}while( bolum == 0 );
System.out.println("Sayının Basamak Sayısı: " + liste.size()); //in here read the number of elements of the "liste"
klavye.close();
}
Edit:
//needs to be like that
while( bolum != 0 );
System.out.println("Sayının Basamak Sayısı: " + liste);
I think that you most likely want your loop stopping condition to be:
while( bolum != 0)
because bolum will only be 0 when there are no more digits left in your number to process. Also, as amit mentions above it could be the case that the user entered 0 when prompted for a number, so you should take that into account.
To obtain a string representation of your ArrayList (showing the elements it contains through their string representations), you can just use
System.out.println("Sayının Basamak Sayısı: " + liste);
No need to convert to an array. This works because it causes liste's toString method to be called (which is why we don't need to call it explicitly).
You must change this line:
}while( bolum == 0 );
To this:
}while( bolum > 0 );
If you want to print your elements in the ArrayList, update your last statement to print as below:
System.out.println("Sayının Basamak Sayısı: " + liste);
Or you can iterate your list and print as :
for(Object i: liste){
System.out.println(i);
}
This will print your individual list items in separate lines.
Also please fix your while condition as while(bolum != 0); as it may terminate after the very first iteration as bolum will be non zero i.e. 1, 2...(!= 0).