I have this block of code and if the main method calls this method and if the parameter is null, then an empty array should be assigned to data. How would I go about doing this?
// Private double array data
private double data[];
// Default constructor that creates a double array having a single element of 0.0
public Stat() {
data = new double[0];
} // End of method
public class StatTester {
public void setData(double[] d) {
if (d == null) {
//where an empty array should be assigned to data
} // End of for loop
} // End of if condition
else {
double[] data = new double[d.length];
for (int c = 0; c < data.length; c++) {
data[c] = d[c];
} // End of for loop
this.data = data;
} // End of else condition
} // End of method
public static void main (String[] args) {
double[] data1 = {50.0, 60.0};
Stat stat1 = new Stat();
data1 = null;
stat1.setData(data1);
System.out.println("stat1 data = " + stat1.toString());
}
Should output:
stat1 data = [50.0, 60.0]
stat1 data = []
Thank you!
Do not redeclare data in setData.
Return as soon as you assign an empty array to data.
Demo:
import java.util.Arrays;
public class Stat {
private double data[];
public Stat() {
data = new double[0];
}
public void setData(double[] d) {
if (d == null) {
data = new double[0];
return;
}
data = new double[d.length];
for (int c = 0; c < data.length; c++) {
data[c] = d[c];
}
}
public static void main(String[] args) {
double[] data1 = { 50.0, 60.0 };
Stat stat1 = new Stat();
stat1.setData(data1);
System.out.println("stat1 data = " + Arrays.toString(stat1.data));
data1 = null;
stat1.setData(data1);
System.out.println("stat1 data = " + Arrays.toString(stat1.data));
}
}
Output:
stat1 data = [50.0, 60.0]
stat1 data = []
Not sure what your problem is.
To assign empty array (array of size 0) to data do same you do in constructor:
data = new double[0];
However, since you've already did that in construction, just do nothing if d == null.
One thing confusing about your code is that you seem to have class Stat with field data and an inner class StatTester that refers to data from Stat via this.data, and does not declare it's own field data. And method setData is in StatTester, not Stat - so your code won't compile.
I'm assuming what you actually wanted is something this:
import java.util.Arrays;
public class Stat {
// Private double array data
private double data[];
// Default constructor that creates a double array having a single element of 0.0
public Stat() {
data = new double[0];
} // End of method
public void setData(double[] d) {
if (d != null) {
this.data = java.util.Arrays.copyOf(d, d.length);
}
} // End of method
public String toString() {
return Arrays.toString(data);
}
public static void main(String[] args) {
double[] data1 = { 50.0, 60.0 };
Stat stat1 = new Stat();
stat1.setData(null);
System.out.println("stat1 data = " + stat1.toString()); // outputs empty array []
stat1.setData(data1);
System.out.println("stat1 data = " + stat1.toString()); // outputs [50.0, 60.0]
}
}
If you want to assign an empty array to data simply do what you already have: data = new double[0];
However as Java is pass by value, where you indicate you want to do this assignment will not work. The reason is the variables data and d and separate. This can be confusing as when they both point to the same array, changes can be made to the array via either reference. However what you are trying to do is not operate on the underlying array, but assign a new array back.
What you need to do is either change the return type of setData to double[] and assign it back or wrap data in another object/ array and then your assigment will work.
you need to make an array with length of zero if you want to print an empty array like [] instead of printing null value:
if (d == null) {
this.data = new double[0];
return;
}
you can also do it in other way just assigning the this.data to d like below and it work correctly but it will print null instead of []:
if (d == null) {
this.data = d;
return;
}
Related
I am trying to find the longest possible path based on how many connections a variable number has, without repeating connections. The way I thought of doing this was creating a list that holds all points that have already been gone through, but when a path ends, and I need to check a new path, all of those old connections remain in the list. How can I restart my list from the initial point?
Putting it in the recursive function itself would just clear the list each time. Is there a better option than using a list?
Relevant code:
package testapp;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.IOException;
import java.util.List;
class TestApp {
// Store list of objects we have already matched with
static List<NumberObject> holdingList = new ArrayList<NumberObject>();
//Test objects
static int[] array1 = {2,2};
static int[] array2 = {3,1};
static int[] array3 = {2,1};
static int[] array4 = {1,1};
static NumberObject eight = new NumberObject(array1, 8);
static NumberObject two = new NumberObject(array2, 2);
static NumberObject three = new NumberObject(array3, 3);
static NumberObject four = new NumberObject(array4, 4);
// Test objects ^^
public static int longestSequence(int[][] grid) {
// TODO: implement this function
// Code exists here not relevant to the problem
//Setting up a new numberList array for testing
NumberObject[] newNumberList = {eight, two, three, four};
NumberObject[] connections1 = {two, four};
NumberObject[] connections2 = {two, three};
//Adding connections
eight.connections = connections1;
four.connections = connections2;
for (NumberObject s: newNumberList){
recursive(s);
}
return 0;
}
public static void recursive(NumberObject object){
for (NumberObject x: holdingList){
System.out.println(x);
}
if (!holdingList.contains(object)){
holdingList.add(object);
if (object.hasConnections()){
NumberObject[] newobject = object.getConnections();
for(NumberObject y: newobject){
recursive(y);
}
}
else {
System.out.println(holdingList.size());
return;
}
}
else {
System.out.println(holdingList.size());
return;
}
}
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int numRows = 0;
int numCols = 0;
String[] firstLine = reader.readLine().split("\\s+");
numRows = Integer.parseInt(firstLine[0]);
numCols = Integer.parseInt(firstLine[1]);
int[][] grid = new int[numRows][numCols];
for (int row = 0; row < numRows; row++) {
String[] inputRow = reader.readLine().split("\\s+");
for (int col = 0; col < numCols; col++) {
grid[row][col] = Integer.parseInt(inputRow[col]);
}
}
int length = longestSequence(grid);
System.out.println(length);
}
}
class NumberObject {
int[] id;
int value;
NumberObject[] connections;
//Constructor
public NumberObject(int[] id, int value){
this.id = id;
this.value = value;
}
//print statement
public String toString(){
return ("NumberOject: Id = " + id + "\nValue = " + value);
}
//Check if it has connections
public boolean hasConnections(){
if (connections == null){
return false;
}
else if (connections.length != 0){
return true;
}
else
return false;
}
//Return the connections it has
public NumberObject[] getConnections(){
return connections;
}
}
Ideally, the image displays what I want to happen.
Instead, all the old branching connections remain on holdingList.
it should be noted paths can branch off to more than two other objects.
Instead of storing the list in a field, you could just pass an instance of a copy of your list to the function as an argument. So the signature of your function recursive would look like:
public static void recursive(NumberObject object, List<NumberObject> visited)
To hide this implementation detail, I recommend writing two functions, whereby the second function just passes an empty list to the other one.
However, I'd choose a different approach since yours acquires as many new lists as entries are in your tree. In the following implementation, you only have one list per "tree end". Moreover, just like in the previous suggestion, this keeps your class stateless.
static List<NumberObject> findLongestPath(NumberObject currentNode) {
if (currentNode.getConnectedNodes().isEmpty()) {
List<NumberObject> result = new ArrayList<>();
result.add(currentNode);
return result;
}
List<NumberObject> longestPath = currentNode.getConnectedNodes().stream()
.map(PathFinder::findLongestPath)
.max(Comparator.comparing(List::size))
.get();
longestPath.add(currentNode);
return longestPath;
}
I have an arraylist that looks like this:
public static ArrayList<ArrayList<String[]>> x = new ArrayList<>();
I store groups of 2 persons in a pair. For example:
[Person1, Person2]
[Person3, Person4]
The algorithm I use right now still makes duplicates, I've tried out hashmaps and iterating through them with for loop but they just give me back the original list.
This is the code:
package com.company;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
public class createGroups
{
public static ArrayList<ArrayList<String[]>> x = new ArrayList<>();
public static void main(String[] args){
//Define names
String[] names = {"Person1", "Person2", "Person3", "Person4"};
try
{
//Create combinations. In a try catch because of the saveFile method.
combination(names, 0, 2);
//Print all the pairs in the Arraylist x
printPairs();
} catch (IOException e)
{
e.printStackTrace();
}
}
static void combination(String[] data, int offset, int group_size) throws IOException
{
if(offset >= data.length)
{
//Create new Arraylist called foo
ArrayList<String[]> foo = new ArrayList<>();
//Create a pair of 2 (data.length = 4 / group_size = 2)
for(int i = 0; i < data.length / group_size; i++)
{
//Add the pair to foo.
foo.add(Arrays.copyOfRange(data, 2 * i, 2 * (i + 1)));
}
//Add foo to x
x.add(foo);
//saveFile(foo);
}
for(int i = offset; i < data.length; i++){
for(int j = i + 1; j < data.length; j++){
swap(data, offset, i);
swap(data, offset + 1, j);
combination(data, offset + group_size, group_size);
swap(data, offset + 1, j);
swap(data, offset, i);
}
}
}
public static void printPairs(){
//Print all pairs
for(ArrayList<String[]> q : x){
for(String[] s : q){
System.out.println(Arrays.toString(s));
}
System.out.println("\n");
}
}
private static void swap(String[] data, int a, int b){
//swap the data around.
String t = data[a];
data[a] = data[b];
data[b] = t;
}
}
The output right now is this:
Output
Every group of 4 names is a 'list' of pairs (Not really a list but that's what I call it)
And this is the desired output:
Desired output
But then you can see that the first and the last list of pairs are basically the same how do I change that in my combination method
The question:
How can I change my combination method so that it doesn't create duplicate groups.
And how can I make the list smaller (The desired output) when printing the created lists.
If I wasn't clear enough or if I didn't explain what I want very well, let me know. I'll try to make it clearer.
Create an object similar to this. It takes 4 strings (2 pairs). Puts the strings into array and sorts this array. That means any combination of strings you put in will be converted into one sorted combination, but the object internaly remembers which person is person1, person2, ...
private class TwoPairs {
private final String person1;
private final String person2;
private final String person3;
private final String person4;
private final String[] persons;
TwoPairs(String person1, String person2, String person3, String person4) {
this.person1 = person1;
this.person2 = person2;
this.person3 = person3;
this.person4 = person4;
persons = new String[4];
persons[0] = person1;
persons[1] = person2;
persons[2] = person3;
persons[3] = person4;
// if we sort array of persons it will convert
// any input combination into single (sorted) combination
Arrays.sort(persons); // sort on 4 objects should be fast
// hashCode and equals will be comparing this sorted array
// and ignore the actual order of inputs
}
// compute hashcode from sorted array
#Override
public int hashCode() {
return Arrays.hashCode(persons);
}
// objects with equal persons arrays are considered equal
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
TwoPairs other = (TwoPairs) obj;
if (!Arrays.equals(persons, other.persons)) return false;
return true;
}
// add methods which you might need
// getters for individual persons
// String getPerson1() { return person1; }
// or perhaps pairs of persons
// String[] getPair1() { return new String[] {person1, person2}; }
// add sensible toString method if you need it
}
Your ArrayList x will change like this
ArrayList<TwoPairs> x = new ArrayList<TwoPairs>();
before adding new TwoPairs object into x check if this list already contains this object.
if (!x.contains(twoPairsObject)) {
x.add(twoPairsObject);
}
I am trying to create an instance variable that is an array. I have many methods that will produce certain statistics about the array. I'm wondering if someone can explain to me if I am going about this the correct way. I'm rather new to Java, so any pointers is greatly appreciated.
When I run the program I get errors, such like Null. I'm not looking to fix these errors now, I'm just wondering if I am going about this the correct way.
My data class:
import java.util.Arrays;
public class Stat {
private double data[];
public Stat()
{
data = new double[1];
data[0]= 0.0;
}
public Stat(double[] d)
{
d = new double[d.length];
}
public double[] getData()
{
return data;
}
public void setData(double[] d)
{
}
Main method:
double[] data = {1,2,2,3,4,5};
Stat stat1 = new Stat(data);
System.out.println(stat1.getData());
System.out.println("stat1 data = " + stat1.toString());
System.out.println("stat1 min = " + stat1.min());
System.out.println("stat1 max = " + stat1.max());
System.out.println("stat1 average = " + stat1.average());
System.out.println("stat1 mode = " + stat1.mode());
System.out.println("stat1 data = " + stat1.toString());
This constructor doesn't really do anything. You pass in an array in d, and then assign d to a different array when you say new, and additionally, d only lives on the stack until the method returns. Whenever this constructor is used data is never initialized and that's where your error is coming from.
Change:
public Stat(double[] d)
{
d = new double[d.length];
}
to something like this:
public Stat(double[] d)
{
data = d;
}
Here's what I ran on my computer:
public class Stat {
private double data[];
public Stat()
{
data = new double[1];
data[0]= 0.0;
}
public Stat(double[] d)
{
data = d;
}
public double[] getData()
{
return data;
}
}
public class JavaTest {
public static void main(String[] args) {
double[] data = {1,2,2,3,4,5};
Stat stat1 = new Stat(data);
System.out.println(stat1.getData()[0]); //outputs 1.0
}
}
Change the constructor to be
public Stat(double[] d)
{
data = d.clone();
}
Because by using the new keyword, your are creating a new empty array. Second error, you can't print directly an array. You have to print its elements, one by one using a for loop for example.
However, I suggest that you override the toString() method
#Override
public String toString(){
return Arrays.toString(data);
}
Then printing your class will output the content of the array
System.out.println("stat1 data = " + stat1);
I got a null pointer exception when accessing a static array from a static member method.
The exception is thrown when i call setData(x, y, z) from a thread. When I debugged it I found out data[0] is null when i try to write to it. I just don't understand how it can be null
public class dataContainer
{
private static final short nrOfDataElements = ids.total_ids;
private static regularDataElement[] data = new regularDataElement[nrOfDataElements];
public static synchronized void getData(final short i, regularDataElement r)
{
if ( (i >= 0) && (i < nrOfDataElements) )
r.set(data[i].getTimestamp(), data[i].getValue());
}
public static synchronized void setData(short i, double ts, long val)
{
if ( (i >= 0) && (i < nrOfDataElements) )
data[i].set(ts, val); //<<-------null pointer exception, debugging showed data[i] == null, (with i = 0 and nrOfDataElements = 12)
}
}
and
public class regularDataElement
{
regularDataElement()
{
set(0, 0);
}
public void set(double _ts, long _val)
{
System.out.println(this.ts + " " + _ts + " " + this.val + " " + _val); System.out.flush();
this.ts = _ts;
this.val = _val;
}
public double getTimestamp()
{
return this.ts;
}
public long getValue()
{
return this.val;
}
private double ts;
private long val;
}
The statement private static regularDataElement[] data = new regularDataElement[nrOfDataElements]; initializes data with an array the size of nrOfDataElements. It does not initialize each element in this array. I.e., all the elements are null.
If you wish to initialize the elements, you should do so yourself. E.g., you could add a static block to handle this:
static regularDataElement[] data = new regularDataElement[nrOfDataElements];
static {
for (int i = 0; i < nrOfDataElements; ++i) {
data[i] = new regularDataElement();
}
}
Did you ever initialize the data array?
private static regularDataElement[] data =
new regularDataElement[nrOfDataElements];
will create an array full of null objects of size nrOfDataElements. It won't actually initialize any elements in the array.
You don't appear to be allocating memory for data[i], which is why you're getting the NPE.
Allocating memory for the array itself is not enough. You need to allocate memory for each element:
for (int i = 0; i < nrOfDataElements; ++i) {
data[i] = new regularDataElement(...);
}
(Replace ... with the actual arguments.)
You never actually create any objects. You must add somewhere:
for (int i = 0; i < data.length; i++) {
data[i] = new regularDataElement();
}
When you initialize an Object array in Java, like data in your code, all elements are by default set to null.
So, you need to populate the data array first, before being able to call any methods against its elements.
Assuming that the regularDataElement class has a no-args (i.e., no parameters) constructor, you could do
static regularDataElement[] data = new regularDataElement[nrOfDataElements];
static
{
for (int i=0; i<nrOfDataElements; i++)
{
data[i] = new regularDataElement();
}
}
Of course, you could have a separate method to initialize the array, e.g.
static regularDataElement[] initialize(int nrOfDataElements)
{
regularDataElement[] elements = new regularDataElement[nrOfDataElements];
for (int i=0; i<nrOfDataElements; i++)
{
elements[i] = new regularDataElement();
}
return elements;
}
and then call that method to create and initialize the data array, replacing the statement
static regularDataElement[] data = new regularDataElement[nrOfDataElements];
with
static regularDataElement[] data = initialize(nrOfDataElements);
Also, as a matter of following established coding conventions, you should name your classes starting with a capital letter, i.e. use RegularDataElement instead of regularDataElement.
I have a class holding a boolean, and two doubles, and then an array of that class, I need the boolean and doubles to have defaults values of false, 0.0, and 0.0, and then I have function that refers to an element of the array and the moment I try to access an one of the variables from the class it throws an exception saying its null. Here is my class and my function calling it.
public class PanelData {
boolean flag = false;
double tempStart = 0.0;
double tempEnd = 0.0;
}
private PanelData[] panelInfo = new PanelData[115];
private void panelInfoHandler (int i, double timeStart, double timeEnd) throws SQLException
{
if (!panelInfo[i].flag) {
delete();
insert();
panelInfo[i].flag = true;
panelInfo[i].tempStart = timeStart;
panelInfo[i].tempEnd = timeEnd;
}
else if (panelInfo[i].tempStart <= timeStart && panelInfo[i].tempEnd >= timeEnd) {
}
else
{
insert();
panelInfo[i].tempStart = timeStart;
panelInfo[i].tempEnd = timeEnd;
}
}
here is how I call the class.
panelInfoHandler(9, parsedStart, parsedEnd);
new PanelData[115] creates an array of 115 null references. Have you populated panelInfo with references to actual objects?
At a minimum, you then need to loop through that array and create new instances of PanelData for each element in the array, e.g.
for (int i = 0; i < panelInfo.length; i++)
panelInfo[i] = new PanelData();
Your array is full of null elements until you initialize it. To clarify, if you create an array of primitive objects, you get an array of default (i.e. 0) values. However, an array of Objects gets created with null elements.
int[] myIntArray = new int[10]; // 10 default values of 0
Integer[] myIntegerArray = new Integer[10]; // 10 null elements
add this line and then assign the values:
if(panelInfo[i] == null) panelInfo[i] = new PanelInfo();
You need to do something like
for(int i=0;i<115; i++)
{
PanelInfo[i] = new PanelData();
}
(Or whatever is the correct Java Syntax)
public class PanelData {
boolean flag = false;
double tempStart;
double tempEnd;
public PanelData() {
flag = false;
tempStart = 0.0;
tempEnd = 0.0;
}
private PanelData[] panelInfo = new PanelData[115];
for(int i = 0; i < 115; i++)
panelInfo[i] = new PanelData();
Creating the default constructor lets you instantiate the variables with the default values (false, 0.0, 0.0) in this case so you can test if you are getting a vanilla object back or not.