• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Rob Spoor
  • Henry Wong
  • Liutauras Vilda
Saloon Keepers:
  • Tim Moores
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Piet Souris
Bartenders:
  • Frits Walraven
  • Himai Minh
  • Jj Roberts

Issue with Arraylist scope and copying it.

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The problem is simple, I need to remove all primes from an arraylist(called al) and print it.

I created a second arraylist(called noPrime) to store all the non-primes, and then stored the noPrime's reference in al. The output was not correct so I printed it twice,


Once inside the solution() method and once in the main method AFTER solution() was already called.

Yet,

When I print the array al in the solution method, it outputs the correct answer.

When I print it in the main method, after calling the solution method, it outputs the incorrect answer.

Example:
Original = [3, 12, 13, 15]
first printing = [12, 15]  (from inside the solution method)
second printing = [3, 12, 13, 15]   (after the solution method is called in main method)

I suspect it is because noPrime has been declared within solution() and it gets destroyed once the solution() has returned. So al, which was holding the reference of noPrime, also gets destroyed? And it comes back to holding its original reference?

Why is this happening?

what does al = noPrime really do?


 
Master Rancher
Posts: 4250
38
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The local variable: al declared on line 19 as a parameter to the method is a copy of the contents of the variable: al passed to the method on line 41.  
The change to the local variable: al on line 30 does not change the value of the variable: al declared on line 36.
Java passes variables by value.
If you want the method's caller to have access to the changed new arraylist, have the method return it.
 
Marshal
Posts: 72406
315
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

Are you supposed to remove prime numbers from a List? That is exactly what you aren't doing. You are creating a second List, and the original List remains unchanged. Norm has suggested one way to get the new List outside your method, but you can actually remove primes from the original List, without using a second List. Please go through the methods of List (including those shown as “declared in Collection”).
As Norm has told you, if you reassign the local variable, that assignment only applies in local scope. If you reassign the variable at a disatance, you are not modiying the object, but replacing it by an object reference incorporating the desired changes.
Why have you go so much code in the main() method? That isn't what it is designed for. Get all the “real” code out into objects and you won't be tempted to use the keyword static. You don't need to iterate every number > 2 to verify that a number is prime.
 
Joe musk
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you so much for the warm welcome and answering my doubt. I have understood exactly what was going wrong and so much more.

Get all the “real” code out into objects and you won't be tempted to use the keyword static


Could you please elaborate this? I understand I can put all the real code into methods outside the main method, and just call them within the main method. Is that what you referring to? I realise that objects are created  using constructors for different classes and they can store methods and variables. But in this particular case, how do I create objects which would replace the "misplaced code" in the main method?

You don't need to iterate every number > 2 to verify that a number is prime.


Is there a more optimised solution than to iterate until the root of the Number?

Thank you for your time and patience.
 
Joe musk
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for taking the time to answer in such great detail. It has helped me to  understand the concept clearly.  
 
Campbell Ritchie
Marshal
Posts: 72406
315
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Joe musk wrote:Thank you so much . . .

That's a pleasure

. . . I can put all the real code into methods outside the main method, and just call them within the main method. Is that what you referring to? . . .

No. Didn't the link I gave you explain it all?


Is there a more optimised solution than to iterate until the root of the Number? . . .

The ideal would be to test only prime numbers, but that necessitates a source of known prime numbers. But you known that all prime numbers > 2 are odd numbers, so test two, then three and go up in steps of two.
 
Joe musk
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

No. Didn't the link I gave you explain it all?


I beg your pardon, it appears I missed the hyperlink. I have gone through it now, and everything makes sense to me now.

so test two, then three and go up in steps of two.


It is incredible how such minute tweaks can cut the running time in half. I initially did think that we never needed to iterate through the even numbers, but I reckoned checking if the no. was odd even or not ,

would take about the same amount of time as

It never occurred to me that we could actually just increment the loop in steps of 2 and skip those even numbers altogether.

This has been very insightful. Learnt a lot.
Thank you for your patience.

^_^
 
Campbell Ritchie
Marshal
Posts: 72406
315
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Use (i & 1) != 0 to test for odd numbers or use ... == 0 for even numbers. It will run faster than ...% 2, and it handles negative numbers better. That trick only works for right operands which are an exact power of two. Remember 1 = 2⁰.
 
Campbell Ritchie
Marshal
Posts: 72406
315
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is a section in Urma Fusco and Mycroft Modern Java in Action (Manning, 2017, page 166) about “Divide only by prime numbers”. Haven't read it recently.
 
Joe musk
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:There is a section in Urma Fusco and Mycroft Modern Java in Action (Manning, 2017, page 166) about “Divide only by prime numbers”. Haven't read it recently.


Thank you, I will look into it.
 
I am displeased. You are no longer allowed to read this tiny ad:
SKIP - a book about connecting industrious people with elderly land owners
https://coderanch.com/t/skip-book
reply
    Bookmark Topic Watch Topic
  • New Topic