Removing an array [duplicate] - java

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Removing an element from an Array (Java) [duplicate]
(15 answers)
Closed 4 years ago.
Got a simple auction program running, only problem is that if a user is removed before auction is closed his/hers bids are supposed to be removed. I dont have it 100% down yet but I think I am on the right path.
The bids have to be arrays and right now it is kinda removed or just moved maybe. This was a the error earlier.
Top Bid:[Wow 400 kr, Boy 311 kr, Man 33 kr, Dude 2 kr]
command>remove user
Name>wow
Wow has been removed from registry
command>list auctions
Auction # 1: Item. Top Bid:[Boy 311 kr, Man 33 kr, Exception in thread "main" java.lang.NullPointerException
public void removeBid(String name) {
for(int a = 0;a < bidIndex; a++) {
if(bids[a].getUser().getName().equals(name)) {
bids[a]=null;
bidIndex--;
break;
}
}
sortBids();
public void sortBids() {
if(bidIndex > 1) {
for(int a = 0; a < bidIndex -1; a++) {
for(int b = a + 1; b < bidIndex; b++) {
if(bids[a] == null || bids[a].getBid() < bids[b].getBid()) {
Bid temp = bids[a];
bids[a] = bids[b];
bids[b] = temp;
}
}

Arrays cannot change size once initialized. If you create an array new String[10]; it will forever have 10 items (which are null by default). Setting an index to null doesn't change this.
String[] items = new String[] {"String1", "String2", "String3"};
items[1] = null;
This arrays would now look like [String1, null, String3].
If you need to change arrays as much as it seems, you're better off using a List or Map.
I would suggest using a HashMap if you want to easily link one object to another. In this case it looks like you'd be linking a String (name) to the Bid object.
Map<String, Bid> bids = new HashMap<String, Bid>();
Bid bid1 = new Bid(/*...*/);
Bid bid2 = new Bid(/*...*/);
// Add bids to the map
bids.put("Wow", bid1);
bids.put("Boy", bid2);
// Get any of these objects
Bid retrievedBid = bids.get("Wow");
// Or remove them
bids.remove("Wow");
HashMaps are similar in concept to associative arrays from other languages, where you have a key -> value relationship. Each key is unique, but the value can repeat.
They can also be converted to arrays if the final result you need is an array.
Bid[] bidsArray = new Bid[0];
bidsArray = bids.values().toArray(bidsArray);

One way you can achieve this is to convert the array to a list and then remove the bid using Java streams and convert back.
List<Bid> bidsList = Arrays.asList(bids);
bidsList = bidsList.stream()
.filter(n -> !n.getUser().getName().equals(name))
.collect(Collectors.toList());
bids = bidsList.toArray(new Bid[bidsList.size()]);

Related

Cannot invoke because Array[] is null [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed last year.
I'm still new to programming and I want to make a program that will take the food order from user until the user presses "n" to stop. But I can't seem to make it work like I want it to.
I want my output to be like this.
Buy food: Burger
Order again(Y/N)? y
Buy Food: Pizza
Order again(Y/N)? n
You ordered:
Burger
Pizza
But my output right now is this.
Buy food: Burger
Order again(Y/N)? y
Buy food: Pizza
Order again(Y/N)? n
You ordered:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Array.getFoodName()" because "food_arr2[i]" is null
at Food.main(Food.java:50)
Here is my code:
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
Food food = new Food();
Array[] food_arr;
boolean stop = false;
String foodName;
int k = 1;
int j = 0;
while(stop == false) {
food_arr = new Array[k];
System.out.print("Buy food: ");
foodName = s.next();
food_arr[j] = new Array(foodName);
food.setFoodArray(food_arr);
System.out.print("Order again(Y/N)? ");
String decide = s.next();
if(decide.equalsIgnoreCase("y")) {
k++;
j++;
}
else if(decide.equalsIgnoreCase("n")) {
stop = true;
}
}
Array[] food_arr2 = food.getFoodArray();
for (int i = 0; i < food_arr2.length; ++i) {
System.out.println("\nYou ordered: ");
System.out.println(food_arr2[i].getFoodName()); //This line is the error according to my output
}
}
I don't know how to fix this and I was hoping for someone to help me.
I think I see what you are trying to do with the k value setting the size of the array you are using.
However, with each iteration of the while loop:
food_arr = new Array[k];
Will create a new empty array each time!
So, for example, on the second iteration
food.setFoodArray(food_arr);
Will set foods array as something like [null, "Pizza"]
Even if this did work, creating a new array each time is not a very efficient method.
I would strongly recommend using a different, dynamically allocated data structure such as an ArrayList and defining it outside the scope of the while loop.
ArrayList<Food> food_arr = new ArrayList<Food>()
// Note that I'm just guessing the data type here - I can't see what you are actually using!
while(stop == false) {
System.out.print("Buy food: ");
foodName = s.next();
food_arr.add(foodName)
// etc, etc
}
food.setFoodArray(food_arr)
// ! Note: You will need to convert the array list into an array
// ! or change the data struture in the Food class
// etc, etc
However, this is just the first solution that popped into my head, check out different kinds of data structures and think about how else you could design this program yourself!

Null Pointer Exception Java Shopping Cart "sort" Method [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
For a school assignment, we have to make a Shopping cart class, along with an Item class and a runner. I figured out how to print out a receipt for items the user enters, but one thing I can't figure out is how to write a sort method using insertion Sorting, which orders each item in the cart by its total cost (price * quantity)
Here is my error:
java.lang.NullPointerException
at ShoppingCart.sort(ShoppingCart.java:54)
at Shopping.main(Shopping.java:32)
I went back to the lines stated
ShoppingCart: (line 54)
public void sort() {
double temp;
int pos = 0;
for (int i = 1;i< cart.length;i++){
temp = cart[i].itemPrice(); //line 54
pos = i;
while (pos>0 && temp < cart[pos-1].itemPrice()) {
cart[pos] = cart[pos-1];
pos--;
}
cart[pos] = cart[i];
}
}
Shopping: (line 32)
cart.sort();
And here is my method to get the price in the Item Class
public double itemPrice(){
return total; }
I'm not sure how to fix the Null Pointer Exception error.
I assume you've got something like this:
Item[] cart = new Item[50];
This creates an array that has room for 50 items.. but all that room is initialized to null. You still have to make 50 items:
for (int i = 0; i < cart.length; i++) cart[i] = new Item();

How to get 2 counts based on two different values in list and check the two counts are equal or not?

I have a list "List issues" this list will hold all the issues from all the projects.
From this "issues" object i can get issues.Project, Issues.Status inside the loop.
I wanted to do the below mentioned operations.
List<Issue> issues = issueCollector.get().getAppropriateIssues();
for (int i=0;i< issues.size();i++)
{
Issue iss = issues.get(i);
}
eg:
**Project IssueKey Status**
PRJ 1 issKey 1 Closed
PRJ 1 issKey 2 Resolved
PRJ 2 isskey 1 Open
PRJ 3 issKey 1 Closed
PRJ 3 issKey 2 Resolved
PRJ 3 issKey 3 Closed
I wanted to get the count of issues with respect to the PROJECT and store it in a variable. How to get the values like below and store in a collection vairable?
eg : PROJECT | Count(Issues)
PRJ 1 2
PRJ 2 1
PRJ 3 3
To get the count of issues in a project with the status in closed or resolved and store it in a variable. How to get the values like below and store in a collection vairable?
eg :
PROJECT | Count(Issues count whose in CLOSED or RESOLVED)
PRJ 1 2
PRJ 3 3
Then from this two variable, i want to check condition like
if(PRJ1(2 issues) == PRJ1(2 issues(with status)))
{
Add this PROJECT to a LIST of STRING
List<STRING> val = new List();
val.add(PROJECT);
}
For flexibility, (it can be that you have to check open issues or sum of this or that), I advise to introduce a small class IssueStatus which keeps all project issue counts. Java 8 allows you to construct it within another class btw.
class IssueStatus {
int numOfClosed = 0;
int numOfResolved = 0;
int numOfOpen = 0;
// not sure if status is string or enum
addStatusCount(String status) {
// logic to inc the num
// eg if "closed", then use numOfClosed++
}
getNumOfClosed() { return numOfClosed; }
getNumOfResolved() { return numOfResolved; }
getNumOfOpen() { return numOfOpen; }
getTotalIssues() { return numOfClosed + numOfResolved + numOfOpen; }
}
You can consider to add a project name to the object. But here, I've used a map to associate a given status to a project.
Map<String, IssueStatus> issueStatusMap = new ...
To populate the map, just use your loop
for (int i=0;i< issues.size();i++) {
Issue iss = issues.get(i);
// check if given project is already in map -> if not, add IssueStatus instance
if (! issueStatusMap.contains(iss.Project)) {
issueStatusMap.put(iss.Project, new IssueStatus());
}
// add issue status cound
issueStatusMap.get(iss.Project).addStatusCount(iss.Status);
}
You can use java 8's stream().forEach( ... ) to fill in the map though. Now, it's easy to have statistic information from your map.
// now you only have to get the data simply
// 1) sum of issues
for(Map.Entry<String, IssueStatus> entry : issueStatusMap.entrySet()) {
s.o.p("project name: " + entry.getKey() + " has " + entry.getValue().getTotalIssues());
}
// or use the sum of the three getNum... methods
// 2) count only closed + resolved
for(Map.Entry<String, IssueStatus> entry : issueStatusMap.entrySet()) {
IssueStatus is = entry.getValue();
s.o.p("project name: " + entry.getKey() + " status count: closed + resolved = " + (is.getNumOfClosed() + is.getNumOfResolved()));
}
Of course you can do all java 8's stream and group by, but I don't advise it because you have to perform another loop each time you're doing your task. This can be an exhaustive operation if the list of issues is very large.
Like in this example, if you want to get sum of counts and sum of "closed" and "resolved" issues by using Collectors.groupingBy, then you're going through that issue list two times. My solution requires one looping, with the cost of some extra heap space to store the objects. And when gathering the data, another small loop is used to go through all project status object instead of all issues. (if there are 100 projects with 5000 issues, then there is a big win)
Finally, to answer your last thing (I admit that this one isn't clear for me)
if(PRJ1(2 issues) == PRJ1(2 issues(with status)))
which is simply
IssueStatus status = issueStatusMap.get("<your projectName>");
if( status.getNum... == status.getNum... ) {
// do something
}
Use java8 collectors api for perform the grouping. check link https://www.mkyong.com/java8/java-8-collectors-groupingby-and-mapping-example/
A simple approach; assuming that you actually have a Project class; you can use a Map<Project, List<Issues>> and from there:
Map<Project, List<Issues>> issuesByProject = new HashMap<>();
for (Issue issue : issues) {
if (issue status ... can be ignored) {
continue;
}
Project proj = issue.getProject();
if (issuesByProject.containsKey(proj)) {
issuesByProject.get(proj).add(issue);
} else {
List newListForProject = new ArrayList<>();
newListForProject.add(issue);
issuesByProject.put(proj, newListForProject);
}
}
This code iterates your list (using the simpler and to-be-preferred for-each looping style). Then we first check if that issue needs to be processed (by checking its status for example). If not, we stop that loop iteration and hop to the next one (using continue). If processing is required, we check if that map contains a list for the current project; if so, we simply add that issue. If not, we create a new list, add the issue, and then put the list into the map.

Not able to generate a unique user-number

I have a problem when I'm trying to generate a unique customer-id in my application. I want the numbers to start from 1 and go up. I have a register-class using tree-map that generates the next customer-number using this code:
public String generateNumber()
{
int number = 1;
for(Map.Entry<String, Forsikringkunde> entry : this.entrySet())
{
if(entry.getValue().getNumber().equals(String.valueOf(number)))
{
number++;
}
}return String.valueOf(number);
}
When I generate customers in my application I get duplicates of the numbers even though I iterate through the map. When creating a customer I create the object, run this method, use a set-method for the ID and adds it to the register, but it doesn't work. Anyone have a solution?
If you're on Java 8, I suggest you try this:
int max = this.values()
.stream()
.map(Forsikringkunde::getNumber)
.mapToInt(Integer::parseInt)
.max()
.orElse(0);
return String.valueOf(max + 1);
Modify the code to instead find the maximum number in your map, and then use that+1:
public String generateNumber()
{
int max = -1;
for(Map.Entry<String, Forsikringkunde> entry : this.entrySet())
{
int entry = Integer.parseInt(entry.getValue().getNumber());
if(entry > max)
{
max = entry;
}
}
return String.valueOf(max + 1);
}
(This mimics your coding style. aioobe's answer shows how to do the same thing more elegantly.)
Your method doesn't work because the map is not iterated in order. For example, here's what happens if you iterate through two users with number 2 and 1 respectively:
Start with "number = 1"
Check if number == 2: it's not, so continue
Check if number == 1: it is, so set number = 2
Now the loop is done and number is 2, even though a user with id 2 already exists. If it had been iterated in order, it would have worked.

Nullpointer exception java runtime [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
The program looks slightly advanced; it is not. Simple manipulation of array.
The program compiles correctly, however, it encounters an exception run-time.
Exception in thread "main" java.lang.NullPointerException
at Ordliste.leggTilOrd(Tekstanalyse.java:85)
at Tekstanalyse.main(Tekstanalyse.java:23)
So there is something wrong with if(s.equalsIgnoreCase(ordArray[k])).
I cannot see why. It even provides the correct output.
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class Tekstanalyse {
public static void main(String[] args) throws FileNotFoundException {
Ordliste ol = new Ordliste();
ol.lesBok("scarlet.text");
ol.leggTilOrd("A");
}
}
class Ordliste {
private int i = 0;
private String[] ordArray = new String[100000];
private int antForekomster;
private int arrStorrelse = 0;
public void lesBok(String filnavn) throws FileNotFoundException {
File minFil = new File(filnavn);
Scanner scan = new Scanner(minFil);
while (scan.hasNextLine()) {
ordArray[i] = scan.nextLine();
//System.out.println(ordArray[i]);
i++;
arrStorrelse++;
}
System.out.println("Array size: " + arrStorrelse + " Capacity: " + ordArray.length);
}
public void leggTilOrd(String s) {
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
} else {
s = ordArray[arrStorrelse];
}
}
}
}
I'm pretty sure the error is right here:
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
} else {
s = ordArray[arrStorrelse]; // <- dangerous
}
}
As I said in the comment, ordArray could contain null elements if the read text file does not contain 100.000 lines of text. If this is the case, the above line would write null to s because s.equalsIgnoreCase(null) is false.
You should think about using a list instead of an array.
private List<String> ordList = new ArrayList<String>();
(or use a different variable name, it is up to you)
Then you can add new entries to the list using ordList.add(scan.nextLine());. This list won't contain any null elements and your mentioned problem should be gone.
I would highly recommend you to simply use a debugger to debug your code , but here goes:
in your lesBok method you fill your array with strings and make a counter arrStorrelse. to be the amount of elements in the array you made. however the array is filled for indexes 0 to n-1. and arrStorrelse is equal to N you did however allocate space in the array for this. so when in leggTilOrd() you iterate the first time and you enter the else clause you do this
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
}
else {
int arrStorrelse2=arrStorrelse;
s = ordArray[arrStorrelse];
}
in that else clause s is set to ordArray[arrStorrElse]; however arrStorrElse is at that moment one higher than the last intialised element of your array. so it sets s to the null pointer.
then the next iteration of your loop in the if clause
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
the s.equalsIgnoreCase() call is done on an s that is null that's where the null pointer exception comes from.
you need to change the arrStorrElse assignment you haven't explained what it should do so i can't do that for you also try to learn how to debug your code here is a usefull link:
http://www.tutorialspoint.com/eclipse/eclipse_debugging_program.htm
I have compiled and tested your code.
s.equalsIgnoreCase(null)
throws nullPointerException.
Maybe you should try to use ArrayList instead of Array to avoid iterating through nulls.
It took me some time to figure out why the NullPointerException occurs and I have to agree with Piotr and Tom: The NPE is caused by the line
s.equalsIgnoreCase(ordArray[k])
and a side-effect in your code. This side-effect is introduced by reassigning the parameter s in the else-branch to null (this value comes from ordArray[arrStorrelse]). After this reassignment happened, you will have something like this:
null.equalsIgnoreCase(ordArray[k])
And voila, there is the NullPointerException.

Categories

Resources