Declaring List before for loop in java - java

Below program gives output : 4 4 4 4 4
package HelloWorld;
import java.util.List;
import com.google.common.collect.Lists;
public class HelloWorld {
public static void main(String args[]) {
List<Product> productList = Lists.newArrayList();
**Product product = new Product();**
for (int i = 0; i < 5; i++) {
product.setId("id:" + i);
productList.add(product);
}
// Printing values
for (int i = 0; i < productList.size(); i++) {
System.out.println(productList.get(i).getId());
}
}
}
This is because Product is declared outside the loop.
But see another program :
package HelloWorld;
import java.util.List;
import com.google.common.collect.Lists;
public class HelloWorld {
public static void main(String args[]) {
**List<String> list = Lists.newArrayList();**
for(int i=0;i<5;i++){
list.add(""+i);
}
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
This gives output : 0 1 2 3 4
May i know why is it printing 0 1 2 3 4 even if the list is declared out side the for loop? I expected it to print 4 4 4 4 4

product is defined outside the for loop, so each time you are doing product.setId("id:" + i); you are overriding the id of the same instance and adding it again to the list. Create the product instance inside the loop
List<Product> productList = Lists.newArrayList();
for (int i = 0; i < 5; i++) {
Product product = new Product();
product.setId("id:" + i);
productList.add(product);
}

In your first example, you only instantiate one Productobject and add that 4 times to your list. However, each time - just before you add it, you overwrite the Id value with the current value of i. Ultimately that will become 4.
In your second example you add a new String object in every pass through of the loop and thus don't overwrite the already set value.

Related

How to fill in the gaps in each array element?

If I have an array like this
int[] array = {2,4,6,8,11};
how to print the gaps between each array element?
Gaps = 3 5 7 9 10
This is my program but the output is always 5 it doesn't print the other gaps is there any method rather than hash set? thank you
`
import java.util.HashSet;
import java.util.Set;
public class test {
public static void main(String[] args) {
int[] array = {2,4,6,8,11};
Set<Integer> set = new HashSet<>();
for(int m : array) {
if( set.add(m));
}//for
for(int i = 1 ; i < set.size() ;i++) {
if(!set.contains(i)) {System.out.println("Gaps = " + set.size()); }
}
}
}
`
In the following solution, I've fixed the logic errors you have made. There are other efficient ways to solve this problem.
import java.util.HashSet;
import java.util.Set;
public class test {
public static void main(String[] args) {
int[] array = {2,4,6,8,11};
Set<Integer> set = new HashSet<>();
for(int m : array) {
if( set.add(m));
}//for
for(int i = 1 ; i < (2* set.size()) + 1 ;i++) {
if(!set.contains(i)) {System.out.println(i); }
}
}
}

What scope does the enhanced for loop variable have in java? [duplicate]

This question already has answers here:
Why does the foreach statement not change the element value?
(6 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 2 years ago.
Is the scope of the enhanced for loop (EFL) variable different for different classes in Java?
When I use an EFL over an ArrayList containing Integers I cannot modify their values directly, however if I do the same thing for an ArrayList of SimpleObjects, defined in my code below, I can change the values of the instance variables with no problem.
import java.util.ArrayList;
class SimpleObject{
public int x;
public SimpleObject() {
this.x = 0;
}
}
public class Simple {
public static void main(String args[]){
// Create an arraylist of Integers and SimpleObjects
ArrayList<Integer> intList = new ArrayList<Integer>();
ArrayList<SimpleObject> soList = new ArrayList<SimpleObject>();
// Add some items to the arraylists
intList.add(1);
intList.add(2);
soList.add(new SimpleObject());
soList.add(new SimpleObject());
// Loop over the arraylists and change some values
for (Integer _int : intList) {
_int = 3; // Why doesn't this work but so.x = 5 below does?
}
for(SimpleObject so : soList) {
so.x = 5;
}
// Loop over the arraylists to print out values
for (Integer _int : intList) {
System.out.println("integer = " + _int);
}
for(SimpleObject so : soList) {
System.out.println(" x = " + so.x);
}
}
}
Actual output:
integer = 1
integer = 2
x = 5
x = 5
Expected output:
integer = 3
integer = 3
x = 5
x = 5
so my question is why doesn't _int = 3; persist in the first EFL, but so.x = 5; does in the second EFL?
// Loop over the arraylists and change some values
for (Integer _int : intList) {
_int = 3; // Why doesn't this work but so.x = 5 below does?
}
for(SimpleObject so : soList) {
so.x = 5;
}
It is because you are assigning the value to _int but you are changing the value in so. Assignment and changing the value are completely different things.
You can understand it better with the following example:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
final List<String> list = new ArrayList<String>();
// Changing - will work
list.add("Hello");
list.add("World");
// Assigning - won't work
list = null;
}
}
If you want to change intList, you can use List:set as shown below:
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> intList = new ArrayList<Integer>();
intList.add(1);
intList.add(2);
for (int i = 0; i < intList.size(); i++) {
intList.set(i, 3);
}
// Display
intList.stream().forEach(System.out::println);
}
}
Output:
3
3
The difference is not that somehow scope rules are different, but that you do two different actions:
so.x = 3 sets the field x of the object referenced by so to 3.
_int = 3 sets _int to 3.
If you changed so.x = 3 to so = new SimpleObject you would see that this too doesn't influence the content of the list you iterate over.
Is the scope of the enhanced for loop (EFL) variable different for different classes in Java?
No. The scope of a variable declared in a for loop or extended for loop is the body of the loop.
Why doesn't _int = 3; persist in the first EFL, but so.x = 5; does in the second EFL?
In the second example, you are not assigning to the loop variable so.
You are assigning to so.x. That is a field of the object that the so variable refers to.
Then later you iterating over the list again and accessing the object which you previously updated.
The so variables in the two loops are different variables.

how to Add ArrayList in ArrayList

I got a problem when insert an ArrayList into ArrayList.
My source code:
import java.util.ArrayList;
public class Ask {
public static void main(String[] args) {
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
ArrayList<ArrayList<String>> result =new ArrayList<ArrayList<String>>();
result.add(mentah);
}
}
How can I create a list based on that data; that will look like:
[[data1,data2,data3],[data4,data5,data6],[data7,data8,data9,data10]]
10 div 3 is 3 (so 3 elements per sublist)
10 mod 3 is 1 (so last sublist has 4 entries)
10 divide by 3 is
3 3 4
Just upgraded the answer of #Narayana Ganesh:
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> result = new ArrayList<List<String>>();
for (int j= 0; j< mentah.size() ; j+=3) {
int end = mentah.size() <= j+2 ? mentah.size() : j+3;
if(mentah.size() - j == 4) end = end +1;
if(j != 9) result.add(mentah.subList(j, end));
}
System.out.println(result);
}
Result:
[[Reza, Fata, Faldy], [Helsan, Dimas, Mamun], [Erik, Babeh, Tio, Mamang]]
A more generic solution would look like:
List<String> allNames = Arrays.asList("Reza", "Fata", ...
List<List<String>> slicedNames = new ArrayList<>();
List<String> sublist = new ArrayList<>();
int sublistTargetLength = 3;
for (String name : allNames) {
sublist.add(name);
if (sublist.size() == sublistTargetLength) {
slicedNames.add(sublist);
sublist = new ArrayList<>();
}
}
if (sublist.size() > 0) {
slicedNames.get(slicedNames.size()-1).addAll(sublist);
}
Some notes:
The above iterates your initial list of names (which can created using that single call to Arrays.asList()); and puts the entries into same-sized lists; which are then added to the slicedNames list of list.
If there is any "remaining" data; that is simply added to the last element of the list of list.
You should prefer to use the interface type List for your variable types; you only use the specific implementation class (ArrayList) when instantiating the list
When iterating anything, prefer the for-each looping style when possible
Try this. You can achieve this using subList method.
import java.util.ArrayList;
import java.util.List;
public class Ask {
public static void main(String[] args) {
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> result = new ArrayList<List<String>>();
for (int j= 0; j< mentah.size() ; j+=3) {
int end = mentah.size() <= j+2 ? mentah.size() : j+3;
result.add(mentah.subList(j, end));
}
for (List<String> item : result) {
System.out.println(" - -"+item);
}
}
}
First create sublists with a maximal size of 3 which will give you something like this
[[Reza, Fata, Faldy], [Helsan, Dimas, Mamun], [Erik, Babeh, Tio], [Mamang]]
then check if the last sublist size is less than 3 if yes add this to the second last sublist and remove the last one
public class Example {
public static void main(String[] args) {
List<String> mentah = new ArrayList<>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> parts = new ArrayList<>();
int sizeOfOriginalList = mentah.size();
int sizeOfSubLists = 3;
for (int i = 0; i < sizeOfOriginalList; i += sizeOfSubLists) {
parts.add(new ArrayList<>(mentah.subList(i, Math.min(sizeOfOriginalList, i + sizeOfSubLists))));
}
if(parts.get(parts.size()-1).size()<sizeOfSubLists){
parts.get(parts.size()-2).addAll(parts.get(parts.size()-1));
parts.remove(parts.get(parts.size()-1));
}
System.out.println(parts);
}
}

Java: How to use functions of a class which has been instantiated by ArrayList

Here is just a simple example. Obviously there are simpler ways to set everything up within the constructor, but the arrayList I'm actually working with has already been set up, I just need to change individual sections of it. There HAS to be a way to call a class's functions in ArrayList, but for the life of me I can't figure out how.
import java.util.ArrayList;
public class ArrayTest{
public static void main(String[] args){
//Here's an example of a regular array:
Length[] lArray = new Length[3];
for (int i = 0; i < 3; i++){
lArray[i].setLength(i + 1);
}
//Here's how I was hoping ArrayList would function:
ArrayList<Length> lList = new ArrayList<Length>(3);
for (int i = 0; i < 3; i++){
lList[i].setLength(i + 1);
// --OR--
lList.setLength(i, i + 1);
}
}
}
Here's the length class:
public class Length{
private int length;
Length(){
length = 0;
}
Length(int s){
length = s;
}
public void setLength(int s){
length = s;
}
}
Thanks!
You add elements to the ArrayList with add.
Since it's an ArrayList<Length>, you add Length objects:
lList.add(new Length());
And in your specific loop :
ArrayList<Length> lList = new ArrayList<Length>(3);
for (int i = 0; i < 3; i++){
Length l = new Length();
l.setLength(i+1);
lList.add(l);
}
BTW, the array initialization is also missing an important initialization :
for (int i = 0; i < 3; i++){
lArray[i] = new Length(); // added
lArray[i].setLength(i + 1);
}
If the ArrayList already contains the elements, and you just want to modify them, you can write something like this:
lList.get(i).setLength(i + 1);
assuming that the ArrayList contains the ith element.
You could create a method with your operation/algorithm like
public void foo(){
System.out.println("some algorithm!");
}
inside Length class. This will operate on each instance of Length class.
And for iterating, you can use
ArrayList<Length> lList = new ArrayList<Length>(3);
for (Length l : lList){
l.foo();
}
This will call everything you code inside foo.

Check the code. Don't understand why logic not work totally [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import com.google.common.collect.*;
public class start {
public static void main(String[] args) {
start ex = new start();
ex.doWork();
}
public void doWork(){
List<String> asu2 = new ArrayList<String>(); // Create and initialization Lists
List<String> rzs = new ArrayList<String>(); // Order collection in descending order
List<String> same = new ArrayList<String>();
for (int j=0;j<10;j++) {
for (int i=0;i<2;i++){ asu2.add("M1");}
asu2.add("M2");
asu2.add("M3");
asu2.add("M4");
asu2.add("M5"); }
System.out.println("Asu size :"+asu2.size());
List<String> asu = Ordering.natural().sortedCopy(asu2); // Order collection in direct order
Collections.reverse(asu);
for (int j=0;j<5;j++) {
for (int i=0;i<2;i++){ rzs.add("M1");}
rzs.add("M2");
rzs.add("M3");
rzs.add("M4");
rzs.add("M5"); }
for (int j=0;j<3;j++) {
for (int i=0;i<2;i++){ rzs.add("M1M2");}
rzs.add("M2M3");
rzs.add("M3M4");
rzs.add("M4M5");
}
for (int j=0;j<2;j++) {
for (int i=0;i<2;i++){ rzs.add("M1M2M3");}
rzs.add("M2M3M4");
rzs.add("M3M4M5");
rzs.add("M1M4M5");
rzs.add("M1M2M5");
}
System.out.println("Rzs size: "+rzs.size());
for (int i=0;i<asu.size();i++){ // Поиск элементов типа M1<-->M1
for (int j=0;j<rzs.size();j++) {
if (asu.get(i).equals(rzs.get(j)))
{ System.out.println("("+asu.get(i)+") ASU <--> ("+rzs.get(j)+") RZS ");
System.out.println("i+ "+i+" j: "+j);
same.add(asu.get(i));
asu.remove(i); rzs.remove(j);
}
}
}
for (int i=0;i<asu.size();i++){ // Поиск элементов M1<-->M1M2
for (int j=0;j<rzs.size();j++) {
if ((asu.get(i).equals(rzs.get(j))) | rzs.get(j).contains(asu.get(i)))
{ System.out.println("("+asu.get(i)+") ASU <--> ("+rzs.get(j)+") RZS ");
same.add(asu.get(i));
asu.remove(i); rzs.remove(j);
}
}
}
System.out.println("Same size: " + same.size());
System.out.println("Rzs size: "+rzs.size());
for (int i=0;i<rzs.size();i++)
System.out.println(rzs.get(i));
System.out.println("Asu size: "+asu.size());
for (int i=0;i<asu.size();i++)
System.out.println(asu.get(i));
}
}
Result:
Same size: 55
Rzs size: 2
M2M3
M3M4
Asu size: 5
M4
M2
M1
M1
M1
The logic is this. If ((asu.get(i).equals(rzs.get(j))) | rzs.get(j).contains(asu.get(i))), it is removed from the list.
Why were the elements still in the ASU (eg M4) and they have a couple (M3M4)?
Sorry for the structure of the code.
Not quite clear on your code, but when you remove an element from an ArrayList that you are iterating through, you do not want to increment the index, otherwise you will skip elements, e.g.:
ArrayList<...> list = ...;
for (int i = 0; i < list.size(); ) {
if (shouldBeRemoved)
list.remove(i);
else
++ i;
}
In other words, if you remove the element at index i, the next element is now at i, not at i + 1.
Since you are skipping elements, then you may find that some that should have been checked are not, and thus are remaining in the list.

Categories