Java - ArrayList of structure Intersections - java

I need to call GetNewItem function million times;
Items XY = GetNewItem(X, Y);
Items XYZ = GetNewItem(XY, Z);
Items XZ = GetNewItem(X, Z);
Items YZ = GetNewItem(Y, Z);
This function aims to
1- find intersection between ArrayList of structure namely
ArrayList<Records> RecordLists
2- and it also calculates the probability for the new ArrayList , this is my code:
class Records {
public int RecordId;
public double Prob;
}
class Items {
public ArrayList<Integer> itemId;
public ArrayList<Records> RecordLists;
public double ItemProb = 0.0;
};
private ArrayList<Records> Intersection(ArrayList<Records> list1, ArrayList<Records> list2) {
ArrayList<Records> Result = new ArrayList<>();
int i = 0, j = 0;
while (i < list1.size() && j < list2.size()) {
if (list1.get(i).RecordId== (list2.get(j).RecordId)) {
Records RecordDetails= new Records();
RecordDetails.RecordId= list1.get(i).RecordId;
RecordDetails.Prob+= 1;
Result.add(RecordDetails);
i++;
j++;
} else if (list1.get(i).RecordId < list2.get(j).RecordId) {
i++;
} else if (list1.get(i).RecordId > list2.get(j).RecordId) {
j++;
}
}
return Result;
}
public Items GetNewItem(Items item1, Items item2) {
Items NewItem = new Items ();
ArrayList<Integer> newItemId = new ArrayList<>();
newItemId.addAll(item1.itemId);
newItemId.addAll(item2.itemId);
NewItem.itemId = newItemId;
NewItem.RecordLists= Intersection(item1.RecordLists,item2.RecordLists);
NewItem.ItemProb = getProb(NewItem.RecordLists);
return NewItem ;
}
private double getProb(ArrayList<Records> RProb) {
double IProb = 0.0;
for (int i = 0; i < RProb.size(); i++) {
IProb += RProb.get(i).Prob;
}
return IProb ;
}
For this code I got 'out of memory error'
I don't know how to save the memory and time, I tried this solution:
java.lang.OutOfMemoryError: Java heap space with NetBeans
but my computer did freeze. I don't know what else I have to do.

Please use java conventions, e.g. variables in camel case, non public variables in classes (use getters/constructor/setters)
I'm not sure why are you getting the intersection that way, with that i and j variables.
Please try:
public <T> List<T> intersection(List<T> list1, List<T> list2) {
List<T> list = new ArrayList<T>();
for (T t : list1) {
if(list2.contains(t)) {
list.add(t);
}
}
return list;
}
If you want to calculate something else maybe do it in a separate method?
Use floats instead of doubles.
Could you please paste whole code? I would like to reproduce this.

Related

We can't add a primitive type value to a ArrayList<Integer> right?? Why is this code working ?? (arrayList should only contain only objects right? )

We can't add a primitive type value to a ArrayList right?? Why is this code working ?? (arrayList should only contain only objects right? )
static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
int aPoints = 0;
int bPoints =0;
for(int i=0;i<a.size();i++){
if(a.get(i)>b.get(i)){
aPoints++;
} else {
if(a.get(i)<b.get(i)) {
bPoints++;
} else {
if(a.get(i)==b.get(i)){
aPoints = aPoints + 0;
bPoints = bPoints + 0;
}
}
}
}
ArrayList<Integer>points = new ArrayList<>();
points.add(aPoints);
points.add(bPoints);
return points;
}

Problems understanding constructors like the one in ArrayList.class

While coding I was trying to declare a class that can create an arraylist of arraylists, but soon enough I found it hard to define a proper constructor for my class. I wanted to define some methods for me to handle the huge outer arraylist(1000*1000), but I might be affected by C and always tried to use something like structdef.
How should I define my class? I guess declaring every lines seperatedly is not a wise choice, and I don't want to use 2D arraylist directly. Besides, how should I define a constructor to get an object that is an 2D arraylist?
//Update here
Below is my code example:
class farbicMap {
//attribute
ArrayList<Integer> farbicUnit = new ArrayList<Integer>();
//constructor
farbicMap () {
for (int i=0;i<1000;++i) {
farbicUnit.add(0);
}//this gives an arraylist with size of 100
//I want to use the above arraylist to construct another list here
}
//method
setUnitValue(int v) {
...
}
}
Seems that I didn't really understand the concept of class... I wanted to use the class to represent a map with some nodes. Now that's much clearer to me.
This is how I understood your consern:
class Test {
public static void main(String[] args) {
Board board = new Board(1000, 1000);
board.put(1, 2, "X");
Object x = board.get(1, 2);
System.out.println("x = " + x);
}
}
class Board {
private final int xSize;
private final int ySize;
private ArrayList<ArrayList<Object>> board = new ArrayList<>();
public Board(int xSize, int ySize) {
this.xSize = xSize;
this.ySize = ySize;
for (int i = 0; i < xSize; i++) {
board.add(getListOfNulls());
}
}
public Object get(int x, int y) {
return board.get(x).get(y);
}
public void put(int x, int y, Object toAdd) {
List<Object> xs = board.get(x);
if (xs == null) {
xs = getListOfNulls();
}
xs.add(y, toAdd);
}
private ArrayList<Object> getListOfNulls() {
ArrayList<Object> ys = new ArrayList<>();
for (int j = 0; j < ySize; j++) {
ys.add(null);
}
return ys;
}
}
You should use Array if size is fixed.

Return the result of each iteration in the loop

I'm doing something that produces the right result. However, it is wrong from a design POV.
The point of the program is to list the result of all the powers of a number up to and including the user-defined limit.
I have a constructor which accepts the base and the exponent from the Scanner. Then a method, which utilises a for loop to calculate the power for each exponent.
Now, the problem is that I'm printing the result from each loop iteration directly from this method. This beats the point of private variables and it being void in the 1st place.
Therefore, I want to define a getter method which returns the result of each power to the output. I used to set them just fine for if/switch statements, but I don't know how to do the same for loops. If I assign the result to a variable within the loop and return that variable from the getter then it will return only the output from the final iteration.
Private implementation
package Chapter6Review;
public class Powers {
private int target;
private int power;
public Powers(int target, int power) {
this.target = target;
this.power = power;
}
public void calculatePower() {
for (int i = 0; i <= power; i++) {
System.out.println((int) Math.pow(target, i));
}
}
/*
public int getPower() {
return
}
*/
}
User interface
package Chapter6Review;
import java.util.Scanner;
public class PowersTester {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter your base: ");
int target = in.nextInt();
System.out.print("Enter your exponent: ");
int power = in.nextInt();
Powers tester = new Powers(target, power);
tester.calculatePower();
}
}
You can simply use a List ;
public List<Integer> calculatePower() {
int p;
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i <= power; i++) {
p = (int) Math.pow(target, i);
result.add(p);
}
return result;
}
Then in you main method, you can iterate the list to print the powers like that :
List<Integer> result = new ArrayList<Integer>();
Powers tester = new Powers(target, power);
result = tester.calculatePower();
for (int i = 0; i < result.size(); i++) {
System.out.println(result.get(i));
}
You could store each of the results in a List:
List<Power> list = new ArrayList<>();
and when you call it add it as well
list.add(new Powers(target, power));
At the end you can iterate over the list like this:
for (Power power : list){
// your code
}
You might consider using streams as well
public List<Integer> calculatePower() {
return IntStream
.rangeClosed(0, power). // iterate from 0 till power inclusive
.mapToObj(i -> (int) Math.pow(target,i))
.collect(Collectors.toList()); // get result as list
}
Thanks for all the answers. Using a list seems to be a good choice.
Since I haven't covered lists yet, I resorted to this solution for now. But I don't like having code that can affect the solution in the main. Ideally, the loop should go in the private implementation.
Main
Powers tester = new Powers(target, power);
for (int i = 0; i <= power; i++) {
tester.calculatePower(i);
System.out.println(tester.getPower());
}
Private implementation
public void calculatePower(int iPower) {
result = (int) Math.pow(target, iPower);
}
public int getPower() {
return result;
}

Generic Matrix Class conversions between different numbers

so I have to create a Matrix class that will generically combine different objects in an array. I know I can do this by checking the types but I want to find a better way. This has to work on Doubles, Integers, Floats, Shorts, Longs, Strings, etc. Here is my current code for this:
public class Matrix<E>{
private E mat2[];
private static final int SIZE = 4;
public Matrix(){
mat2 = (E[]) new Object[SIZE];
}
public Matrix(E a1, E a2, E b1, E b2){
mat2 = (E[]) new Object[SIZE];
mat2[0] = a1;
mat2[1] = a2;
mat2[2] = b1;
mat2[3] = b2;
}
public void add(Matrix<E> info){
if(mat2[0] instanceof Number){
for(int i = 0; i < SIZE; i++){
Double tmp = ((Double)info.getElement(i)).doubleValue();
Double other = tmp + ((Double)mat2[i]).doubleValue();
mat2[i] = (E) other;
}
}
}
public E getElement(int index){ return mat2[index];}
public String toString(){
String info = "[";
for(int i = 0; i < SIZE; i++){
info += "\t" + mat2[i];
info += (i % 2 == 1) ? "\t]\n[" : "";
}
return info.substring(0, info.length() - 1);
}
public static void main(String... arg){
Matrix<Integer> matInt = new Matrix<Integer>(new Integer(1), new Integer(0), new Integer(0), new Integer(1));
Matrix<Integer> matInt2 = new Matrix<Integer>(new Integer(1), new Integer(0), new Integer(0), new Integer(1));
System.out.println(matInt);
Matrix<String> matStr = new Matrix<String>("One", "Two", "Three", "Four");
System.out.println(matStr);
matInt.add(matInt2);
System.out.println(matInt);
}
}
Now let me draw your attention to this method:
public void add(Matrix<E> info){
if(mat2[0] instanceof Number){
for(int i = 0; i < SIZE; i++){
Double tmp = ((Double)info.getElement(i)).doubleValue();
Double other = tmp + ((Double)mat2[i]).doubleValue();
mat2[i] = (E) other;
}
}
}
I am assuming Double right now so that if it is a floating point number, it will maintain the decimal but if it isn't I was hoping to cut it off. I can easily accomplish what I need by doing something along the lines of:
public void add(Matrix<E> info){
if(mat2[0] instanceof Number){
for(int i = 0; i < SIZE; i++){
if(type == Double){
Double tmp ((Double)info.getElement(i)).doubleValue();
Double other = tmp + ((Double)mat2[i]).doubleValue();
mat2[i] = (E) other;
}
if(type == Integer){
//do integer instead
}
if(type == String){
//do String instead
}
}
}
}
but I am wondering if I can find a more Generic war of doing this without all the checks. The program is for an assignment so I must use generics. The idea is to be able to add and multiply the types in the array 'mat2'. So if I have Integer types they need to add together. If I have Strings they need to add together as well.

Merge and order Lists

For any two ascending sorted ArrayList<Integer> such as
List<Integer> l1 = new ArrayList<Integer>();
l1.add(1);
l1.add(2);
l1.add(5);
l1.add(10);
and
List<Integer> l2 = new ArrayList<Integer>();
l2.add(1);
l2.add(3);
l2.add(5);
l2.add(11);
how to merge them into an ArrayList<Integer> whose values are
1,1,2,3,5,5,10,11
Update
Realised that Integer oversimplifies the problem; in fact these are lists of class
public class Tuple {
public boolean isComment;
public int location;
public String text;
public Tuple(boolean isAComment, int aLocation, String aText) {
isComment = isAComment;
location = aLocation;
text = aText;
}
}
As suggested, a valid solution requires a sorting, where location is first criterion, whether it is a comment is the second criterion.
This answer does not contain code, you'll have to figure it out for yourself.
Add the Lists to one another using addAll.
Sort the Lists using Collections.sort
Are you implementing merge-sort?
The "bycicle"-way (O(n)):
public List<Integer> merge (List<Integer> l1, List<Integer> l2) {
List<Integer> result = new ArrayList<>();
int i1 = 0, i2 = 0;
while (i1 < l1.size() && i2 < l2.size())
if (l1.get(i1) < l2.get(i2))
result.add (l1.get(i1++));
else
result.add (l2.get(i2++));
while (i1 < l1.size())
result.add (l1.get(i1++));
while (i2 < l2.size())
result.add (l2.get(i2++));
return result;
}
In case of List<Tuples> that wouldn't change much, just make your Tuple Comparable:
public class Tuple implement Comparable <Tuple> {
public boolean isComment;
public int location;
public String text;
public Tuple(boolean isAComment, int aLocation, String aText) {
isComment = isAComment;
location = aLocation;
text = aText;
}
public int compareTo (Tuple that) {
if (location == that.location)
return Boolean.compare (isComment, that.isComment);
else
return Integer.compare (location, that.location);
}
}
Then, instead of using < operator, you should use l1.get(i1).compareTo(l2.get(i2)) < 0

Categories