PriorityQueue add Element will change the element, weird bug - java

public class Main {
public static class EE implements Comparable<EE> {
int x;
int[] rac;
public EE(int x, int[] rac) {
this.x = x;
this.rac = rac;
}
public int compareTo(EE that) {
if (this.x != that.x) return this.x - that.x;
else return this.rac[2] = that.rac[2];
}
}
public static void main(String[] args) {
int [][] ary = {
{1,1,3,3},
{1,3,2,4},
{2,3,3,4}};
PriorityQueue<EE> pq = new PriorityQueue<EE>();
for (int[] rec : ary) {
EE e1 = new EE(rec[0], rec);
EE e2 = new EE(rec[2], rec);
pq.add(e1);
pq.add(e2);
}
}
This piece of code I'm running, everything is fine but when the second for loop is entered, rec is [1, 3, 2, 4] initially, when pq.add(e1) get called, value of rec will become [1, 3, 3, 4] anyone can explain why this happens? Thank you in advance!

The preoblem is in comapreTo method:
return this.rac[2] = that.rac[2];
It's returning always the latter that.rac[2]. It should be:
return this.rac[2] == that.rac[2];

Related

java.awt.Queue cannot be accessed from outside package

The version of java: SDK 1.8.0_151
IDE: IDEA IntelliJ
import java.awt.Queue;
import java.util.LinkedList;
public class SimpleMovingAverage {
private final Queue<Double> window = new LinkedList<Double>();
private final int period;
private double sum;
public SimpleMovingAverage(int period) {
assert period > 0 : "Period must be a positive integer";
this.period = period;
}
public void newNum(double num) {
sum += num;
window.add(num);
if (window.size() > period) {
sum -= window.remove();
}
}
public double getAvg() {
if (window.isEmpty()) {return 0.0;} // technically the average is undefined
return sum / window.size();
}
public static void main(String[] args) {
double[] testData = {1, 2, 3, 4, 5, 5, 4, 3, 2, 1};
int[] windowSizes = {3, 5};
for (int windSize : windowSizes) {
SimpleMovingAverage ma = new SimpleMovingAverage(windSize);
for (double x : testData) {
ma.newNum(x);
System.out.println("Next number = " + x + ", SMA = " + ma.getAvg());
}
System.out.println();
}
}
}
The code above is coming from https://rosettacode.org/wiki/Averages/Simple_moving_average#Java
When I create a Class, called SimpleMovingAverage and copy the code from the above website, an error is reported.
'java.awt.Queue' is not public in 'java.awt'. Cannot be accessed from outside package
How to solve it?
You need java.util.Queue not java.awt.Queue, which can hold whatever you want
The java.awt package is about UI, graphics and images: Documentation, and the java.awt.Queue is here to hold java.awt.Event elements
For Improvement ONLY : for the implementation of a Circular FIFO, here some infos
Is there a fixed sized queue which removes excessive elements?
Basic implem of a CircularQueue
Which could give something like
public void newNum(double num) {
window.add(num);
}

error when calling main method with parameters

I have the following code:
public class classroom{
public static void main(Integer[] args) {
int teachers = args[0];
int students = args[1];
int desks = args[2];
int computers = args[3];
double ratio = students/desks;
if (teachers == 1) {
if (computers >= students) {
if (ratio <= 6) {
System.out.println("this classroom is vald");
}
}
}
else {
System.out.println("this classroom is not valid");
}
}
}
I run the code as classroom.main(1, 2, 3, 4), and java returns the following error: 'identifier expected'. Any idea how I should solve this problem?
You should solve this problem call method as:
Classroom.main(new Integer[]{1, 2, 3, 4});
I think you need ... operator, Calling Classroom.main(1, 2, 3, 4) will require you to change the method Argument with three dot operator. By using Three dot operator ... You can pass integer arguments without explicitly creating array.
public class ClassRoom {
public static void main(String[] args) {
ClassRoom.main(1, 2, 3, 4);
}
private static void main(Integer... args) {
for (Integer i : args) {
System.out.println("Argument [ " + i + " ] = " + args[i-1]);
}
}
}
You should call the function by classroom.main(new Integer[] { 1, 2, 3, 4 }), instead of classroom.main(1, 2, 3, 4).
Because the function declares as classroom.main(Integer[] args), but not classroom.main(int a, int b, int c, int d).
Another advice: Java class name should use Camel Case for the Java naming convention.

How does this recursion make sense?

import java.util.*;
public class ArrayList5 {
static int max(ArrayList list) { // to be completed
if (list.size() == 0) {
return 0;
}
else
{
int first = (Integer) list.get(0);
list.remove(0);
if (first > max(new ArrayList(list)))
{
return first;
}
else
{
return max(list);
}
}
}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
Collections.addAll(list, 4, 5, 3, 2, 3, 1, 3);
// int t=Console.readInt("Enter Target:");
int res1 = max(new ArrayList(list));
System.out.println("max=" + res1);
}
}
I don't understand why the max(new ArrayList(list))) part is required. Why does it have to create a new one and why can't it continue to work with the one list?
Also why doesn't it get caught in a loop (it's recursion so it will keep sending up a new list so I don't understand why 'first' isn't going to be 4 every time)?
Actually, there is a lot of superfluous code that is not required and make the code cumbersome/more difficult to read/understand.
You can simplify the code a lot and get rid of any reference to ArrayList which are not really necessary and by using proper generic at the right places, make the code actually readable.
You don't need to cast or create list all over the place.
public class ArrayList5 {
static int max(final List<Integer> list) {
if(list.isEmpty()) return 0;
final int head = list.get(0);
final List<Integer> tail = list.subList(1, list.size());
return (head > max(tail)? head:max(tail));
}
public static void main(final String... args) {
final int res1 = max(Arrays.asList(4, 5, 3, 2, 3, 1, 3));
System.out.printf("max=%d", res1);
}
}
You should try this:
static int max(ArrayList<Integer> list) {...}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
Collections.addAll(list, 4, 5, 3, 2, 3, 1, 3);
// int t=Console.readInt("Enter Target:");
int res1 = max(new ArrayList(list));
System.out.println("max=" + res1);
}
The compiler is probably throws a warning because you don't declare the type of the ArrayList.

How to copy elements of an array in superclass into an array in subclass in java?

Eg:
class A
{
int array[] = {1,2,3,4,5}
}
class B extends A
{
int new_array[];
}
Now here, I want to that new_array in class B should be containing the same elements as array in class A.
NOTE :
I want to copy, but want to take care of that case where when we do any change in the copied array then the change should "not" be reflected in the original array.
class A {
int array[] = {1, 2, 3, 4, 5};
}
class B extends A {
int new_array[] = array;
public void afterCopyArrayPrint() {
for (int i : new_array) {
System.out.println(i);
}
}
}
public class ArrayTest {
public static void main(String[] args) {
B ob = new B();
ob.afterCopyArrayPrint();
}
}
// TRY THIS
public class Array
{
int[] a = {1, 2, 3, 4, 5};
int length = a.length;
}
class Array2 extends Array
{
int[] newArray = new int[super.length];
public static void main(String[] args)
{
Array obj = new Array();
Array2 obj2 = new Array2();
for (int i = 0; i < obj.length; i++) {
obj2.newArray[i] =obj.a[i];
System.out.println(obj2.newArray[i]);
}
}
}
Try this:
public class A {
int arrayA[] = {1,2,4,5,3}; //unsorted array
}
public class B extends A {
int arrayB[];
public void exampleOfCopySortPrint() {
arrayB = Arrays.copyOf(arrayA, 5); // copy the values of arrayA into arrayB
// arrayB is now an entirely new array
Arrays.sort(arrayB); // this sorts the array from small to large
// print all elements in arrayB
for (int i : arrayB) {
System.out.println(i); // 1, 2, 3, 4, 5 (sorted)
}
}
}
You don't need to also add the field in class B.
If you don't add the modifier public or protected on the array field like protected int array[]; in class A, make sure you place the 2 classes in the same folder/package.
After studying and surfing the web, I finally managed learned how to copy an array without using loops.
The solution is as follows :
class A
{
int array[] = {1, 2, 3, 4, 5};
}
class B extends A
{
int copyArray[] = array.clone();
}
I found this clone() method really helpful!

When using ArrayList<int[][]> how to see if an element is already in the list?

Using the public boolean contains(Object o) in the ArrayList library does not work in this case. Consider
ArrayList<int[][]> test = new ArrayList<>();
int[][] one = {
{1,2,3},
{4,5,6}
};
int[][] two = {
{1,2,3},
{4,5,6}
};
int[][] three = {
{9,7,5},
{1,2,4},
{5,6,7}
};
test.add(one);
System.out.println(test.contains(one));
System.out.println(test.contains(two));
System.out.println(test.contains(three));
The above code returns
true
false
false
Is there a way to check for equality between the two and make sure that no duplicate values enter the list?
The easiest approach I know is to extract it into a method using Arrays.deepEquals(Object[], Object[]), something like -
public static boolean contains(List<int[][]> al, int[][] toFind) {
for (int[][] arr : al) {
if (Arrays.deepEquals(arr, toFind)) {
return true;
}
}
return false;
}
Then you can test it like
public static void main(String[] args) {
ArrayList<int[][]> test = new ArrayList<int[][]>();
int[][] one = { { 1, 2, 3 }, { 4, 5, 6 } };
int[][] two = { { 1, 2, 3 }, { 4, 5, 6 } };
int[][] three = { { 9, 7, 5 }, { 1, 2, 4 }, { 5, 6, 7 } };
test.add(one);
if (contains(test, two)) {
System.out.println("Found two");
}
}
Output is
Found two
One solution would be to wrap the arrays in a class that provides an appropriate equals implementation.
class SquareArray {
private int[][] array;
public SquareArray(int[][] array) {
this.array = array;
}
public int[][] getArray() {
return array;
}
#Override
public boolean equals(Object o) {
return (o instanceof SquareArray) &&
Arrays.deepEquals(array, ((SquareArray)o).array);
}
#Override
public int hashCode() {
return Arrays.deepHashCode(array);
}
#Override
public String toString() {
return Arrays.deepToString(array);
}
}
Now you would use a List<SquareArray>; for instance:
int[][] a = {{1,2,3}, {4,5,6}};
int[][] b = {{1,2},{3,4},{5,6}};
int[][] c = {{1,2,3}, {4,5,6}};
SquareArray x = new SquareArray(a);
SquareArray y = new SquareArray(b);
SquareArray z = new SquareArray(c);
List<SquareArray> list = new ArrayList<>();
list.add(x);
System.out.println(list.contains(x));
System.out.println(list.contains(y));
System.out.println(list.contains(z));
true
false
true
Reference:
Arrays.deepEquals
Arrays.deepHashCode
Arrays.deepToString
I'd like to propose another solution using Java 8 streams and predicates:
The Stream#anyMatch method may be used to check whether the given list contains a certain element. The required predicate can be build concisely using Arrays#deepEquals:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GenericContainsTest
{
public static void main(String[] args)
{
List<int[][]> list = new ArrayList<int[][]>();
int[][] one =
{ { 1, 2, 3 },
{ 4, 5, 6 } };
int[][] two =
{ { 1, 2, 3 },
{ 4, 5, 6 } };
list.add(one);
if (list.stream().anyMatch(e->Arrays.deepEquals(e, two)))
{
System.out.println("Found two");
}
}
}
However, you mentioned that your intention is to...
... make sure that no duplicate values enter the list
In this case, you should at least consider to not use a List, but a Set - particularly, a Set<SquareArray> using the SquareArray class that arashajii proposed in his answer.
contains method use the method equals(e) and when you use equals on array it's the same thing as using == hence you check for reference equality, not content.
To check if two arrays are equals you have to use Arrays.equals(array1, array2) or Arrays.deepEquals(nestedArray1, nestedArray2) for nested arrays.

Categories

Resources