I got a Post class which will contain some posts of a page!
public static class Post {
String cation;
int id;
PageInfo[] usersLiked;
boolean isValid = false;
Post (String caption, int id, PageInfo[] usersLiked) {
this.cation = caption;
this.id = id;
this.usersLiked = usersLiked;
}
}
I defined an array of Posts which some of them are not actually used yet and they're made to be used later.
For example i have 2 posts but my array of posts has a size of 5.
Post[] postArray = new Post[5];
I specify used posts with "isValid".
Then how can i don't get a NullPointerException when i'm counting valid posts size?
public int getPostLength () {
int cnt = 0;
for (int i = 0; i < 5; i++) { // 5 : arraysize
if (postArray[i].isValid == true)
cnt++;
}
return cnt;
}
public int getPostLength () {
int cnt = 0;
for (int i = 0; i < postArray.length; i++) {
if (postArray[i] != null && postArray[i].isValid)
cnt++;
}
return cnt;
}
You could do it via java streams :
long cnt= Arrays.stream(postArray).filter(Objects::nonNull).filter(Post::isValid).count()
If the postArray has only two post element, then the if statement will cause a null pointer exception.
You can't call a method or access a property of a null object.
Wrap the existing if statement with a null check.
public int getPostLength () {
int cnt = 0;
for (int i = 0; i < 5; i++) {
if (postArray[I] != null) {
if (postArray[i].isValid == true)
cnt++;
}
}
return cnt;
}
Related
My question is: how can I see the Tuple result in the process method if it was created in the check method? How am I able to use it there, if it was created in a private method?
public class Problem13 {
private Tuple<Integer> costs;
private Tuple<String> names;
private Tuple<Integer> result;
private int budget;
private int minDelta, minCost, totalCost;
public void process(String fileName) {
if (!read(fileName))
return;
if (budget >= totalCost) {
System.out.println("You can buy all items");
return;
}
if (budget < minCost) {
System.out.println("You cannot buy items");
return;
}
minDelta = -1;
int n = costs.getLength();
Set<Integer> interval = new IntegerInterval(0, n - 1);
for (int k = n - 1; k > 0; --k) {
Combinations<Integer> combinations = new Combinations<Integer>(interval, k);
combinations.produce((tuple) -> !check(tuple));
if (minDelta == 0)
break;
}
if (result == null)
System.out.println("No solution found");
else {
int k = result.getLength();
for (int j = 0; j < k; ++j)
System.out.printf("%s ", names.get(result.get(j)));
System.out.printf("(%d)\n", minDelta);
}
}
public static void main(String[] args) {
new Problem13().process("data/input13.txt");
}
private boolean check(Tuple<Integer> tuple) {
int k = tuple.getLength();
int currentCost = 0;
for (int i = 0; i < k; ++i) {
int j = tuple.get(i);
currentCost += costs.get(j);
if (currentCost > budget)
return false;
}
int d = budget - currentCost;
if (minDelta < 0 || d < minDelta) {
minDelta = d;
result = new ArrayTuple<>(k);
for (int i = 0; i < k; ++i)
result.set(i, tuple.get(i));
}
return minDelta == 0;
}
private means private to the class. So Problem13 can see anything defined in that class, whether private, public, protected or package private.
Also, the access modifier of the method only affects who can call it, not where the results can be seen. For instance, if result was defined as a public field, any class (not just Problem13) could see it.
You can find many good breakdowns of access modifiers out there on the Interwebs. Here's one.
There is a class called PageInfo which is like this:
I assume the max size of arrays is 5.
public static class PageInfo {
String username;
PageInfo[] followings;
Post posts[];
PageInfo (String username,PageInfo[] followings,Post[] posts) {
this.username = username;
this.followings = followings;
this.posts = posts;
}
public int getPostLength () {
int cnt = 0;
for (int i = 0; i < 5; i++) {
if (posts[i] != null )
cnt++;
}
return cnt;
}
public int getFollowingLength () {
int cnt = 0;
for (int i = 0; i < 5; i++) {
if (followings[i] != null )
cnt++;
}
return cnt;
}
}
and there is a Post class like:
public static class Post {
String cation;
int id;
PageInfo[] usersLiked;
Post (String caption, int id, PageInfo[] usersLiked) {
this.cation = caption;
this.id = id;
this.usersLiked = usersLiked;
}
}
I want to declare a user with constructor like:
PageInfo[] allusers = new PageInfo[5];
allusers[0] = new PageInfo("John", "54321", new PageInfo[5], new Post[5]);
allusers[0].followings[0] = allusers[1];
allusers[0].posts[0] = new Post("John Post", 100, new PageInfo[5]);
The "getPostLength" works well.
but when "GetFollowingLength" returns me 0. why? and how to fix it?
how can i add "followings" to the allusers[x] later in the project?
It seems that "followings" hasn't been initialized yet and the're still Null. how can i properly initalize them?
I think what you're missing is that an array is initialized with null values when you do "new PageInfo[5]" or something similar. So followings is initialized as an empty array (all values null). Same with allusers. So "allusers[0].followings[0] = allusers[1];" does not do anything here. It just sets the value to null, which it already is.
I don't know what exactly you want to achieve, so I'm not sure how you could improve your code. One way could be to initialize an array like this:
Foo array = new Foo[42];
for(int i=0; i<array.length; i++
{
array[i] = new Foo();
}
I have made a function for objects to reserve seats in a area. But if 2 objects enter the function at the same time they get the same seats. How do I solve this?
The Function getFreeChairs, returns the chair positions. And sets the Fan. But if two fans enter it at the same time they both get the same seats.
Sven
package model;
import actors.Fan;
import java.util.ArrayList;
import java.util.List;
/**
* Created by sveno on 12-10-2016.
*/
public class Vak {
private static int autoId = 1;
private String naam;
private int rijen, stoelenperrij, id;
private List<ArrayList> rows = new ArrayList<>();
private Fan fan = null;
public Vak(String naam, int rijen, int stoelenperrij) {
this.naam = naam;
this.rijen = rijen;
this.stoelenperrij = stoelenperrij;
this.id = autoId;
autoId++;
for (int i = 0; i < rijen; i++) {
rows.add(new ArrayList<Fan>());
}
for (ArrayList row : rows) {
for (int j = 0; j < stoelenperrij; j++) {
row.add(fan);
}
}
}
public void removeReserved(int rij, List<Integer> stoelen){
for (int i = 0; i < stoelen.size()-1; i++) {
//De reserveer alle stoelen
ArrayList<Fan> stoel = rows.get(rij);
stoel.set(stoelen.get(i),fan);
}
}
public int getRijen() {
return rijen;
}
public int getStoelenperrij() {
return stoelenperrij;
}
public List<ArrayList> getRows() {
return rows;
}
public int[] getFreeChairs(int aantalStoelen, Fan fan){
//Check for free seats
int count = 1;
int[] stoelenleeg = new int[aantalStoelen+1];
for (int j = 0; j < rows.size(); j++) {
for (int k = 0; k < rows.get(j).size(); k++) {
if (rows.get(j).get(k) == null){
stoelenleeg[count-1] = k;
count++;
//Not enough seats next to each other
if(count==aantalStoelen+1){
stoelenleeg[aantalStoelen] = j+1;
for (int o = 0; o < stoelenleeg.length-1; o++) {
ArrayList<Fan> stoel = rows.get(j);
stoel.set(stoelenleeg[o],fan);
}
return stoelenleeg;
}
}else{
//Not enough seats
stoelenleeg = new int[aantalStoelen+1];
count=1;
}
}
}
return stoelenleeg;
}
}
If your code is used in a concurrent context (multiple threads), you need to make sure that your code is thread safe.
It means that, only one single thread(person) should be able to call the getFreeChairs function(reserve a seat at a time)
The easy way to do it in java is to use the synchronized key word in the method definition:
public synchronized int[] getFreeChairs(int aantalStoelen, Fan fan){
...
}
My assignment asks me to make a TV show program, where I can input shows, delete, modify and sort them. What I'm stuck on is the sorting part. With the show, it asks for the name, day a new episode premieres, and time. Those are the keys I need to sort it by.
The program prompts the user to input one of those keys, then the program needs to sort (sorting by day will sort alphabetically).
I made a class and used an array. Here is the class:
public class showInfo
{
String name;
String day;
int time;
}
And the method to sort by time in the code:
public static void intSort()
{
int min;
for (int i = 0; i < arr.length; i++)
{
// Assume first element is min
min = i;
for (int j = i+1; j < arr.length; j++)
{
if (arr[j].time < arr[min].time)
{
min = j;
}
}
if (min != i)
{
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < arr.length; i++)
{
System.out.println(arr[i].name + " - " + arr[i].day + " - " + arr[i].time + " hours");
}
}
When I call it and output it in the main, it only shows "TV Shows by Time" and not the list. Why is this?
Also, I need to make ONE method that I will be able to use to sort both the day AND the name (both Strings). How can I do this without using those specific arrays (arr[i].name, arr[i].day) in the method?
Any help would be greatly appreciated! Thanks in advance!
In this part of your code
if (min != i) {
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
You're just changing the time when you should move the whole object instead. To fix it, the code must behave like this:
if (min != i) {
//saving the object reference from arr[i] in a temp variable
showInfo temp = arr[i];
//swapping the elements
arr[i] = arr[min];
arr[min] = temp;
}
I̶t̶ ̶w̶o̶u̶l̶d̶ ̶b̶e̶ ̶b̶e̶t̶t̶e̶r̶ ̶t̶o̶ ̶u̶s̶e̶ ̶ Arrays#sort ̶w̶h̶e̶r̶e̶ ̶y̶o̶u̶ ̶p̶r̶o̶v̶i̶d̶e̶ ̶a̶ ̶c̶u̶s̶t̶o̶m̶ ̶̶C̶o̶m̶p̶a̶r̶a̶t̶o̶r̶̶ ̶o̶f̶ ̶t̶h̶e̶ ̶c̶l̶a̶s̶s̶ ̶b̶e̶i̶n̶g̶ ̶s̶o̶r̶t̶e̶d̶ ̶(̶i̶f̶ ̶y̶o̶u̶ ̶a̶r̶e̶ ̶a̶l̶l̶o̶w̶e̶d̶ ̶t̶o̶ ̶u̶s̶e̶ ̶t̶h̶i̶s̶ ̶a̶p̶p̶r̶o̶a̶c̶h̶)̶.̶ ̶S̶h̶o̶r̶t̶ ̶e̶x̶a̶m̶p̶l̶e̶:̶
showInfo[] showInfoArray = ...
//your array declared and filled with data
//sorting the array
Arrays.sort(showInfoArray, new Comparator<showInfo>() {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
//basic implementation
if (showInfo1.getTime() == showInfo2.getTime()) {
return showInfo1.getName().compareTo(showInfo2.getName());
}
return Integer.compare(showInfo1.getTime(), showInfo2.getTime());
}
});
//showInfoArray will be sorted...
Since you have to use a custom made sorting algorithm and support different ways to sort the data, then you just have to change the way you compare your data. This mean, in your current code, change this part
if (arr[j].time < arr[min].time) {
min = j;
}
To something more generic like
if (compare(arr[j], arr[min]) < 0) {
min = j;
}
Where you only need to change the implementation of the compare method by the one you need. Still, it will be too complex to create and maintain a method that can support different ways to compare the data. So the best option seems to be a Comparator<showInfo>, making your code look like this:
if (showInfoComparator.compare(arr[j], arr[min]) < 0) {
min = j;
}
where the showInfoComparator holds the logic to compare the elements. Now your intSort would become into something more generic:
public static void genericSort(Comparator<showInfo> showInfoComparator) {
//your current implementation with few modifications
//...
//using the comparator to find the minimum element
if (showInfoComparator.compare(arr[j], arr[min]) < 0) {
min = j;
}
//...
//swapping the elements directly in the array instead of swapping part of the data
if (min != i) {
int temp = arr[i].time;
arr[i].time = arr[min].time;
arr[min].time = temp;
}
//...
}
Now, you just have to write a set of Comparator<showInfo> implementations that supports your custom criteria. For example, here's one that compares showInfo instances using the time field:
public class ShowInfoTimeComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
return Integer.compare(showInfo1.getTime(), showInfo2.getTime());
}
}
Another comparator that uses the name field:
public class ShowInfoNameComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
return showInfo1.getName().compareTo(showInfo2.getName());
}
}
Now in your code you can call it like this1:
if (*compare by time*) {
genericSort(showInfoArray, new ShowInfoTimeComparator());
}
if (*compare by name*) {
genericSort(showInfoArray, new ShowInfoNameComparator());
}
if (*another custom rule*) {
genericSort(showInfoArray, new ShowInfoAnotherCustomRuleComparator());
}
where now you can implement a custom rule like compare showInfo objects using two or more fields. Taking as example your name and day fields (as stated in the question):
public class ShowInfoNameAndDayComparator implements Comparator<showInfo> {
#Override
public int compare(showInfo showInfo1, showInfo showInfo2) {
//write the comparison logic
int nameComparisonResult = showInfo1.getName().compareTo(showInfo2.getName());
if (nameComparisonResult == 0) {
return showInfo1.getDay().compareTo(showInfo2.getDay());
}
return nameComparisonResult;
}
}
1: There are other ways to solve this instead using lot of if statements, but looks like that's outside the question scope. If not, edit the question and add it to show another ways to solve this.
Other tips for your current code:
Declare the names of the classes using CamelCase, where the first letter of the class name is Upper Case, so your showInfo class must be renamed to ShowInfo.
To access to the fields of a class, use proper getters and setters instead of marking the fields as public or leaving the with default scope. This mean, your ShowInfo class should become into:
public class ShowInfo {
private String name;
private String day;
private int time;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//similar for other fields in the class
}
Use selection sort algorithm which is easy to implement,
for (int i = 0; i < arr.length; i++)
{
for (int j = i + 1; j < arr.length; j++)
{
if (arr[i].time > arr[j].time) // Here ur code that which should be compare
{
ShowInfo temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
no need to check min element. go through this wiki http://en.wikipedia.org/wiki/Selection_sort
Why not you use a Collection for this sort of a thingy to work. Moreover, in your added example, you are simply changing one attribute of a given object, while sorting, though you not changing the position of the object as a whole, inside the given list.
Create a List which will contain the references of all the Shows, now compare each attribute of one Show with another, in the List. Once the algorithm feels like, that swapping needs to be done, simply pick the reference from the List, save it in a temp variable, replace it with a new reference at this location, and set duplicate to the one stored in the temp variable. You are done, List is sorted :-)
Here is one small example for the same, for help :
import java.io.*;
import java.util.*;
public class Sorter {
private BufferedReader input;
private List<ShowInfo> showList;
public Sorter() {
showList = new ArrayList<ShowInfo>();
input = new BufferedReader(
new InputStreamReader((System.in)));
}
private void createList() throws IOException {
for (int i = 0; i < 5; i++) {
System.out.format("Enter Show Name :");
String name = input.readLine();
System.out.format("Enter Time of the Show : ");
int time = Integer.parseInt(input.readLine());
ShowInfo show = new ShowInfo(name, time);
showList.add(show);
}
}
private void performTask() {
try {
createList();
} catch (Exception e) {
e.printStackTrace();
}
sortByTime(showList);
}
private void sortByTime(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
if (showList.get(j).getTime() <
showList.get(min).getTime()) {
min = j;
}
}
if (min != i) {
ShowInfo temp = showList.get(i);
showList.set(i, showList.get(min));
showList.set(min, temp);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
public static void main(String[] args) {
new Sorter().performTask();
}
}
class ShowInfo {
private String name;
int time;
public ShowInfo(String n, int t) {
name = n;
time = t;
}
public String getName() {
return name;
}
public int getTime() {
return time;
}
}
EDIT 2 :
For sorting By Name you can use this function :
private void sortByName(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
int value = (showList.get(j).getName()).compareToIgnoreCase(
showList.get(min).getName());
if (value < 0)
min = j;
}
if (min != i) {
ShowInfo temp = showList.get(i);
showList.set(i, showList.get(min));
showList.set(min, temp);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
EDIT 3 :
Added Comparable<?> Interface, to the existing class to perform sorting based on specified input. Though one can improve on the logic, by using Enumeration, though leaving it for the OP to try his/her hands on :-)
import java.io.*;
import java.util.*;
public class Sorter {
private BufferedReader input;
private List<ShowInfo> showList;
private int command;
public Sorter() {
showList = new ArrayList<ShowInfo>();
input = new BufferedReader(
new InputStreamReader((System.in)));
command = -1;
}
private void createList() throws IOException {
for (int i = 0; i < 5; i++) {
System.out.format("Enter Show Name :");
String name = input.readLine();
System.out.format("Enter Time of the Show : ");
int time = Integer.parseInt(input.readLine());
ShowInfo show = new ShowInfo(name, time);
showList.add(show);
}
}
private void performTask() {
try {
createList();
} catch (Exception e) {
e.printStackTrace();
}
System.out.format("How would you like to sort : %n");
System.out.format("Press 0 : By Name%n");
System.out.format("Press 1 : By Time%n");
try {
command = Integer.parseInt(input.readLine());
} catch (Exception e) {
e.printStackTrace();
}
sortList(showList);
}
private void sortList(List<ShowInfo> showList) {
int min;
for (int i = 0; i < showList.size(); i++) {
// Assume first element is min
min = i;
for (int j = i+1; j < showList.size(); j++) {
showList.get(j).setValues(command);
int value = showList.get(j).compareTo(showList.get(min));
if (value < 0) {
min = j;
}
}
if (min != i) {
Collections.swap(showList, i, min);
}
}
System.out.println("TV Shows by Time");
for(int i = 0; i < showList.size(); i++) {
System.out.println(showList.get(i).getName() +
" - " + showList.get(i).getTime());
}
}
public static void main(String[] args) {
new Sorter().performTask();
}
}
class ShowInfo implements Comparable<ShowInfo> {
private String name;
private int time;
private int command;
public ShowInfo(String n, int t) {
name = n;
time = t;
}
public String getName() {
return name;
}
public int getTime() {
return time;
}
public void setValues(int cmd) {
command = cmd;
}
public int compareTo(ShowInfo show) {
int lastCmp = 1;
if (command == 0) {
lastCmp = name.compareTo(show.name);
} else if (command == 1) {
if (time < show.time) {
lastCmp = -1;
} else if (time == show.time) {
lastCmp = 0;
} else if (time > show.time) {
lastCmp = 1;
}
}
return lastCmp;
}
}
I'm using the Arrays.sort method to sort an array of my own Comparable objects. Before I use sort the array is full, but after I sort the array and print it to System nothing is printing out. EDIT. the array prints nothing at all. not empty line(s), just nothing.
here is the code for my method which uses sort :
public LinkedQueue<Print> arraySort(LinkedQueue<Print> queue1)
{
Print[] thing = new Print[queue1.size()];
LinkedQueue<Print> newQueue = new LinkedQueue<Print>();
for(int i = 0; i <queue1.size(); i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
Arrays.sort(thing);
for(int j = 0;j<thing.length-1;j++)
{
System.out.println(thing[j]); //printing does not work here
newQueue.enqueue(thing[j]);
}
return newQueue;
}
and here is the class for the Comparable object called Print.
public class Print implements Comparable<Print>
{
private String name;
private int numPages,arrivalTime,startTime,endTime;
public Print(String n, int p, int time, int sTime, int eTime)
{
name = n;
numPages = p;
arrivalTime = time;
startTime = sTime;
endTime = eTime;
}
public int getPages()
{
return numPages;
}
public int compareTo(Print other)
{
if(this.getPages()<other.getPages())
return -1;
else if(this.getPages()>other.getPages())
return 1;
else
return 0;
}
public String toString()
{
return name+"("+numPages+" pages) - printed "+startTime+"-"+endTime+" minutes";
}
}
Your last for loop doesn't print the last element in the array. If the array has only one element, it won't print anything at all. Change to:
for (int j = 0; j < thing.length; j++) //clean code uses spaces liberally :)
{
System.out.println(thing[j]);
newQueue.enqueue(thing[j]);
}
or (if supported by the JDK/JRE version used):
for (Print p : thing)
{
System.out.println(p);
newQueue.enqueue(p);
}
I hope the problem is this part of code
for(int i = 0; i <queue1.size(); i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}
replace the above with
for(int i = 0; !queue1.isEmpty() ; i++)
{
Print ob = queue1.dequeue();
thing[i] = ob;
System.out.println(thing[i]); //printing works here
}