I am trying to compare two Strings based on which the boolean dontuse will be set. For practice I have set string as static but they may vary (Please dont ask how I get these Strings it a whole big beast in itself).
What I am trying to do is, check if String 'allofmycode' has any element more then 'codeChoosen' then 'dontuse' is false. But if both of the string are equal then its is false or if the string has same element written several times then also false.
So, for
(1) it will be false as it contains AB & CD which are extra.
(2) will be true as it has the same element but is duplicate.
I hope it make sense, any suggestions or help? Thanks
public static void main(String[] args) {
boolean dontuse = false;
String codeChoosen = "EX,ZX";
String allofmycode = "EX,AB,CD,EX"; //(1) dontuse=false
//String allofmycode = "EX,EX,ZX"; //(2) dontuse =true
List<String> mycodeChoosen = Arrays.asList(codeChoosen.split("\\s*,\\s*"));
System.out.println("Selected : \t " + mycodeChoosen);
List<String> allofmyresult = Arrays.asList(allofmycode.split("\\s*,\\s*"));
System.out.println("All : \t" + allofmyresult);
if (mycodeChoosen.equals(allofmyresult)) {
dontuse = true;
} else {
for (int i = 0; i < mycodeChoosen.size(); i++) {
if (allofmyresult.contains(mycodeChoosen.get(i))) {
System.out.println(mycodeChoosen.get(i));
}
}
}
System.out.println("\n[DONT USE IS] : \t " + dontuse);
}
For example in basic english, If you have Apple, Orange and Banana; and I say people with Apple and Orange are not coming to my party. But you also have Banana so you are allowed to come to the party. But if you had two Apples or Apple and Banana then you are not allowed. I hope it make sense.
dontuse = !allofmyresult.stream().anyMatch(str -> !mycodeChoosen.contains(str));
As the problem seems to require only a view as sets, do:
static Set<String> codes(String list) {
Set<String> set = new HashSet<>();
Collections.addAll(set, list.split("\\s*,\\s*"));
return set;
}
String codeChoosen = "EX,ZX";
String allofmycode = "EX,AB,CD,EX"; //(1) dontuse=false
Set<String> choosen = codes(codeChoosen);
Set<String> all = codes(allofmycode);
boolean dontuse = choosen.equals(all);
// all.containsAll(choosen)
The original code probably was meant to do:
if (mycodeChoosen.equals(allofmyresult)) {
dontuse = true;
} else {
dontuse = true;
for (int i = 0; i < mycodeChoosen.size(); i++) {
if (allofmyresult.contains(mycodeChoosen.get(i))) {
dontuse = false;
break;
}
}
}
Related
I'm having a little trouble with a fairly simple assignment, but couldn't find an answer here that seemed to work.
I need to have a 2D ArrayList that contains staff data, and then be able to run a separate function that allows the user to input a staff member's name, searches the ArrayList for that name, and if it exists, display the full row of data.
Here's what I've got so far:
The ArrayList
List<List<String>> staffArrayString = new ArrayList<>();
staffArrayString.add(Arrays.asList("Steven George", "12 York Road", "07123456678", "Permanent", "York", "27000/yr"));
staffArrayString.add(Arrays.asList("Rina Veyer", "20 Leeds Road", "08987987765", "Part Time", "Leeds", "10/hr"));
staffArrayString.add(Arrays.asList("Brian Lym", "13 Bradford Road", "07123234345", "Permanent", "Bradford", "27000/yr"));
The search function
public void staffNameSearch() {
System.out.println("Enter name of staff member:");
String staffName = in.next();
boolean found = false;
int row = 0;
for (int i = 0; i < staffArrayString.size(); i++) {
for (int j = 0; j < staffArrayString.get(i).size(); j++) {
if (staffArrayString.get(i).get(j).equals(staffName)) {
row = staffArrayString.get(i).size();
found = true;
}
}
}
if (found = true) {
System.out.print(staffArrayString.get(row) + " ");
}
}
I'm currently getting an output of 'Exception in thread "main" java.lang.IndexOutOfBoundsException' at the print line on the end there, but I can't for the life of me work out why. I'd appreciate any advice on this (especially if it's some obvious and stupid mistake on my part!).
The error is occuring because you are setting row to something unrelated to the row counter. When you discover the row (variable i) which has the name in the jth element, set row=i.
Be careful about if (found = true) - it is incorrect; prefer:
a) if (found)
b) if (found == true)
For efficiency, include && !found in the for loops so they exit as soon as you find something.
You can use for each loop for simpler.
System.out.println("Enter name of staff member:");
String staffName = in.next();
boolean found = false;
String[] foundArray;
for(String[] staffArray: staffArrayString){
for(String str : staffArray){
if(str.equals(staffName)){
foundArray = staffArray;
found = true;
break;
}
}
}
if (found == true) {
System.out.print(foundArray + " ");
}
You might be able to simplify the code a little bit by using a Map and a Staff class.
For example, the Staff class
public class Staff{
String name;
String address;
String id; // ?
boolean permanent; // Or a enum if there are more than 2 values
String city; // ?
int payrate;
boolean hourly;
#Override
public String toString(){ // Easily convert the class to a String
return String.format("%s %s %s %s %s $%d/%s",
name,
address,
id,
permanent ? "Permanent" : "Part-time",
city,
payrate,
hourly ? "hr" : "yr");
}
}
And for the code to read it
private Map<String, Staff> staffDirectory; // String is the name in lowercase
public void staffNameSearch() {
// Code
if(staffDirectory.containsKey(staffName)){ // Make sure staffName is lowercase
System.out.print(staffDirectory.get(staffName) + " ");
} else {
System.out.println("Name not found");
}
}
This way you can avoid using loops and get O(1) efficiency.
I am going to be honest and up front here. This is homework, but I have become desperate and am looking for anyone to assist me. I have been working on this off and on for over a month and have gone to my instructor multiple times. Basically this program needs to create and sort a linked list that has an int, string and double in each node. It needs to be able to sort by each data type as well as print in input order but once I figure one out I can transfer it to the other data types. Please, everything needs to be "hand made", please do not use any built in commands as I need to create everything as per my instructor's demands.
I attempted to make the linked list and then sort it, but I ran into a problem so I decided to try and sort the list as I create it.
For example: Input the first node, then input the next node in front/behind the first, then put the next where it needs to go... and so forth.
Here is my code (I only focus on the strings):
String repeat = "y";
list1 fChr = null;
list1 p = fChr;
list1 copy = null;
//list1 dCopy = null;
//list1 iCopy = null;
list1 fd = fChr;//front of the double list
list1 fi = fChr;//front of the integer list
list1 fStr = fChr;//front of the string list~
list1 pStr = fStr;
boolean inserted = false;
int iii = 0;
String sss = "";
double ddd = 0.0;
while(repeat.equals("y"))//while the user agrees to adding a new node
{
if(fChr == null)// if the front is empty
{
fChr = new list1();//create a new node by calling object and sets it as the front
p = fChr;
copy = fChr;
sss = fChr.GetS();
iii = fChr.GetI();
ddd = fChr.GetD();
copy.SetS(sss);
copy.SetI(iii);
copy.SetD(ddd);
System.out.println("(1)");
}
else
{
System.out.println("(2)");
if(p!=null)
{
System.out.println("p = "+ p.GetS());
if(p.next != null)
{
System.out.println("p.next = "+ p.next.GetS());
System.out.println("p.next.next = "+ p.next.next.GetS());
}
}
p = fChr;
while(p.next != null)//finds the end of the Linked list
{
System.out.println("(3)");
p = p.next;//moves the pointer p down the list
}
list1 NextNode = new list1();//
p.next = NextNode;
sss = NextNode.GetS();
iii = NextNode.GetI();
ddd = NextNode.GetD();
copy = NextNode;
String gg = "hi";//tests to see if the setter is actually changing the value inside copy(it is not, it prints b)
copy.SetS(gg);
copy.SetI(iii);
copy.SetD(ddd);
System.out.println(copy.GetS());
System.out.println("p = "+ p.GetS());
}
pStr = fStr;
//System.out.println(copy.GetS()+"*");
inserted = false;
if(fStr == null)
{
System.out.println("(4)");
fStr = copy;//fStr = fChr;
inserted = true;
//System.out.println("p.next.next = "+ p.next.next.GetS());
}
else if(copy.GetS().compareTo(fStr.GetS()) < 0)
{
System.out.println("(5)");
//System.out.println("1)p.next.next = "+ p.next.next.GetS());
copy.next = fStr;//ERROR ON THIS LINE
System.out.println("2)p.next.next = "+ p.next.next.GetS());
System.out.println("fChr.next: "+fChr.next.GetS());
fStr = copy;
System.out.println("3)p.next.next = "+ p.next.next.GetS());
inserted = true;
System.out.println("p = "+ p.GetS());
System.out.println("p.next = "+ p.next.GetS());
System.out.println("4)p.next.next = "+ p.next.next.GetS());
}
else if(fStr.next == null && fStr != null)
{
System.out.println("(6)");
fStr.next = copy;
inserted = true;
}
else
{
System.out.println("(7)");
pStr = fStr;
System.out.println("RIP (8)");
while(pStr.next != null && inserted == false)
{
System.out.println("(9)");
System.out.println("RIP");
if(copy.GetS().compareTo(pStr.next.GetS()) < 0)//if it goes between 2 nodes
{
System.out.println("(10)");
copy.next = pStr.next;
pStr.next = copy;
inserted = true;
}
else
{
System.out.println("(11)");
pStr = pStr.next;
}
if(pStr.next == null && inserted == false)// it goes at the end(not necessary bc of the (in order) part)
{
System.out.println("(12)");
pStr.next = copy;
}
}
}
repeat = JOptionPane.showInputDialog("Would you like to add a node [y/n]");
System.out.println("End of Loop");
}
System.out.println(fStr.GetS());
PrintMenu(fChr, fi, fd, fStr);// sends the user to the menu screen
}
From all of my print statements I have (what I think) found the problem. This code runs through twice and upon hitting "y" for the third time, prints "(3)" in an infinite loop. I have found that (say the input for the strings is "c" then "b") "p" is equal to "c", p.next is equal to "b" and p.next.next is equal to "c". So, p is in an infinite loop. I have no idea why it does this, I have a theory that it could be because the front(fChr) changes and then "p" points to it and is just kinda drug along. I also just realized that me trying to set "copy" equal to "NextNode" was unsuccessful and copy just holds the value inside p.next(which is NextNode). That seems correct, but when I try to put something else in, it doesn't work. I could be testing this incorrectly and in that case the setter is correct. Setting is one of the main problems that I seem to be having. I will try to answer as many questions as I can if anyone has any.
Also here is the object in case you would like to see it. Thank you for your time, any help will be appreciated. Please if possible try to keep it relatively simple this is a high school assignment and I am so close and am stumped on how to fix what is wrong. Also, you may have noticed, but I have to use private variables. I am not asking for someone to give me a program that works, I am just asking if you know why what is going wrong is happening and if you know how to fix it. Thank you from the bottom of my heart!
import javax.swing.JOptionPane;
public class list1
{
private int i;
private String s;
private double d;
private String ss = null;
private int ii = 0;
private double dd = 0.0;
list1 next = null;
public list1()
{
String str;
s=JOptionPane.showInputDialog("Enter a String");
String temp =JOptionPane.showInputDialog("Enter an Integer");
i = Integer.parseInt(temp);
String temp2 =JOptionPane.showInputDialog("Enter a Double");
d = Double.parseDouble(temp2);
}
public double GetD()
{
return d;
}
public String GetS()
{
return s;
}
public int GetI()
{
return i;
}
public void SetS(String x)
{
ss = x;
}
public void SetI(int y)
{
ii = y;
}
public void SetD(double z)
{
dd = z;
}
}
I want to do a specific sort. I am using java's comparable interface which means the return of my compare method must return -1 +1 or 0 depending on the equality of the two compared, then I am sorting using Collections. My trouble comes from how I wish to compare.
I have a key that is made up of either of the following
[keyName]
[siteName].[keyName]
[siteName].[pageName].[keyName]
so as an example "mysite.alampshade.color"
the tricky part is the sites must be sorted first, followed by keyname, followed by pageName. but firstly by the keynames, then site name, in the order of the number of sections to the property. Sorry. its a little complicated, an example may help. here is the order they must be:
alpha
beta
charlie
sitea.alpha
sitea.charlie
sitea.pagea.beta
sitea.pageb.beta
sitea.pagea.charlie
siteb.alpha
siteb.delta
siteb.pagef.alpha
siteb.pageb.echo
siteb.pageb.golf
siteb.pagea.hotel
siteb.pageb.hotel
siteb.pagec.hotel
I have tried many different ways and have thrown away code a few times but still cant get it perfect. some pseudocode would be of great help if not some java.
EDIT:
to add another possibly simplier to understand example
the following is sorted how I need it
a
b
c
z
a.b
a.c
a.d
a.z
a.b.a
a.c.a
a.b.b
a.b.c
a.c.c
a.a.d
b.a
b.b
b.z
b.a.a
b.b.a
b.a.b
c.c.f
Another option, making it recursive you avoid the problem if there is ever more entries.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class SortTest {
public static void main(String[] args) {
String[] test = new String[]{
"a",
"b",
"b.a",
"b.a.a",
"a.a.a",
"a.b.a",
"a.a",
"a.b",
"b.a.b",
"b.b.a"
};
Arrays.sort(test, new Comparator<String>() {
int compareComplexList(List<String> a, List<String> b, List<int[]> positions, int order ) {
int minimum = a.size() < b.size() ? a.size() - 1 : b.size() - 1;
if (a.get(positions.get(minimum)[order]).compareTo(b.get(positions.get(minimum)[order])) != 0)
return a.get(positions.get(minimum)[order]).compareTo(b.get(positions.get(minimum)[order]));
else if (order < minimum - 1) return compareComplexList(a,b, positions, ++order);
else return Double.compare(a.size(),b.size());
}
public int compare(String a, String b) {
List<String> partsA = Arrays.asList(a.split("\\."));
List<String> partsB = Arrays.asList(b.split("\\."));
List<int[]> orders = new ArrayList<int[]>();
orders.add(new int[] {0});
orders.add(new int[] {0,1});
orders.add(new int[] {0,2,1});
return compareComplexList(partsA, partsB, orders,0);
}
});
System.out.println("Sorted: "+Arrays.toString(test));
}
}
Should be good now.
public int compare(String a, String b) {
String[] partsA = a.split("\\.");
String[] partsB = b.split("\\.");
// If first term is different, we exit.
if (partsA[0].compareTo(partsB[0]) != 0) return partsA[0].compareTo(partsB[0]);
// Else, first term is identical.
else {
// Same number of parts
if (partsA.length == partsB.length) {
// 2 parts, we compare the 2nd part.
if (partsA.length == 2) {
return partsA[1].compareTo(partsB[1]);
// 3 parts, we compare the 3rd part first, then the 2nd part
} else {
if (partsA[2].compareTo(partsB[2]) != 0) return partsA[2].compareTo(partsB[2]);
return partsA[1].compareTo(partsB[1]);
}
// Different number of parts
} else {
// If A has only 1 part, it's first
if (partsA.length == 1) return -1;
// If B has only 1 part, it's first
if (partsB.length == 1) return 1;
// Case 2 vs 3 parts, we compare the 3rd part with the 2nd part of the other. If it's equal, the shorter is first.
if (partsA.length == 3) {
if (partsA[2].compareTo(partsB[1]) != 0) return partsA[2].compareTo(partsB[1]);
else return 1;
} else {
if (partsA[1].compareTo(partsB[2]) != 0) return partsA[1].compareTo(partsB[2]);
else return -1;
}
}
}
}
My other answer started getting too gnarly. Here's a better, more natural solution:
public class StrangeComparator {
private static class Entry implements Comparable<Entry> {
// What to split with.
static final String dot = Pattern.quote(".");
// The parts.
final String key;
final String page;
final String site;
public Entry(String s) {
String [] parts = s.split(dot);
switch (parts.length) {
case 1:
key = parts[0];
page = "";
site = "";
break;
case 2:
key = parts[1];
page = "";
site = parts[0];
break;
case 3:
key = parts[2];
page = parts[1];
site = parts[0];
break;
default:
throw new IllegalArgumentException("There must be at least one part to an entry.");
}
}
#Override
public int compareTo(Entry t) {
int diff = site.compareTo(t.site);
if ( diff == 0 ) {
diff = page.compareTo(t.page);
}
if ( diff == 0 ) {
diff = key.compareTo(t.key);
}
return diff;
}
#Override
public String toString () {
return (site.length() > 0 ? site + "." : "")
+ (page.length() > 0 ? page + "." : "")
+ key;
}
}
public void test() {
String[] test = new String[]{
"alpha",
"beta",
"charlie",
"zeta", // Added to demonstrate correctness.
"sitea.alpha",
"sitea.charlie",
"sitea.pagea.beta",
"sitea.pageb.beta",
"sitea.pagea.charlie",
"siteb.alpha",
"siteb.delta",
"siteb.pagef.alpha",
"siteb.pageb.echo",
"siteb.pageb.golf",
"siteb.pagea.hotel",
"siteb.pageb.hotel",
"siteb.pagec.hotel"
};
Arrays.sort(test);
System.out.println("Normal sort: " + Separator.separate("\n", "\n", test));
Entry[] entries = new Entry[test.length];
for ( int i = 0; i < test.length; i++ ) {
entries[i] = new Entry(test[i]);
}
Arrays.sort(entries);
System.out.println("Special sort: " + Separator.separate("\n", "\n", entries));
}
public static void main(String args[]) {
new StrangeComparator().test();
}
}
Output order is:
alpha
beta
charlie
zeta
sitea.alpha
sitea.charlie
sitea.pagea.beta
sitea.pagea.charlie
sitea.pageb.beta
siteb.alpha
siteb.delta
siteb.pagea.hotel
siteb.pageb.echo
siteb.pageb.golf
siteb.pageb.hotel
siteb.pagec.hotel
siteb.pagef.alpha
Which kinda does what you say but doesn't match your example.
Here's an alternative - if a component is found to contain less that 3 parts then parts are added at the start to take up the slack. It then uses a sort order array to define which columns should be compared next:
public void test() {
String[] test = new String[]{
"alpha",
"beta",
"charlie",
"zeta", // Added to demonstrate correctness.
"sitea.alpha",
"sitea.charlie",
"sitea.pagea.beta",
"sitea.pageb.beta",
"sitea.pagea.charlie",
"siteb.alpha",
"siteb.delta",
"siteb.pagef.alpha",
"siteb.pageb.echo",
"siteb.pageb.golf",
"siteb.pagea.hotel",
"siteb.pageb.hotel",
"siteb.pagec.hotel"
};
Arrays.sort(test);
System.out.println("Normal sort: "+Arrays.toString(test));
Arrays.sort(test, new Comparator<String>() {
// How many columns to pad to.
final int padTo = 3;
// What to pad with.
final String padWith = "";
// What order to compare the resultant columns in.
final int[] order = {0, 2, 1};
#Override
public int compare(String s1, String s2) {
String[] s1parts = padArray(s1.split(Pattern.quote(".")), padTo, padWith);
String[] s2parts = padArray(s2.split(Pattern.quote(".")), padTo, padWith);
int diff = 0;
for ( int i = 0; diff == 0 && i < order.length; i++ ) {
diff = s1parts[order[i]].compareTo(s2parts[order[i]]);
}
return diff;
}
String [] padArray(String[] array, int padTo, String padWith) {
String [] padded = new String[padTo];
for ( int i = 0; i < padded.length; i++ ) {
padded[padded.length - i - 1] = i < array.length ? array[i]: padWith;
}
return padded;
}
});
System.out.println("Special sort: "+Arrays.toString(test));
}
prints (more or less):
Normal sort: [alpha,
beta,
charlie,
sitea.alpha,
sitea.charlie,
sitea.pagea.beta,
sitea.pagea.charlie,
sitea.pageb.beta,
siteb.alpha,
siteb.delta,
siteb.pagea.hotel,
siteb.pageb.echo,
siteb.pageb.golf,
siteb.pageb.hotel,
siteb.pagec.hotel,
siteb.pagef.alpha,
zeta]
Special sort: [alpha,
beta,
charlie,
sitea.alpha,
sitea.charlie,
siteb.alpha,
siteb.delta,
zeta,
siteb.pagef.alpha,
sitea.pagea.beta,
sitea.pageb.beta,
sitea.pagea.charlie,
siteb.pageb.echo,
siteb.pageb.golf,
siteb.pagea.hotel,
siteb.pageb.hotel,
siteb.pagec.hotel]
There does seem to be some ambiguity in your requirements but this code is structured so you can, with trivial tweaks, achieve most interpretations of your comparison quite simply.
Is there a way to check if a string contains something while not being case sensitive?
For example: (this code is invalid it's just for you to get a basic understanding of my question)
String text = "I love ponies";
if(text.contains().equalsIgnoreCase("love") {
// do something
}
EDIT:
-------- Still not working
ooh, turns out it's not working. Here's what I'm using.
(it's a curse filter for a game)
public void onChat(PlayerChatEvent event) {
Player player = event.getPlayer();
if (event.getMessage().contains("douche".toLowerCase()) || /* More words ... */) {
event.setCancelled(true);
player.sendMessage(ChatColor.GOLD + "[Midnight Blue] " + ChatColor.RED + "Please Don't Swear.");
}
}
It works with lowercase but not uppercase.
return text.toLowerCase().contains(s2.toLowerCase());
Or another way would be
Pattern.compile(Pattern.quote(s2), Pattern.CASE_INSENSITIVE).matcher(text).find();
It would be easier if you use StringUtils#containsIgnoreCase from Apache Commons library
If you can't add a third party library, you can still use the code because is free to use. Check the online source code.
Test:
public class QuestionABCD {
public static boolean containsIgnoreCase(String str, String searchStr) {
if (str == null || searchStr == null) {
return false;
}
int len = searchStr.length();
int max = str.length() - len;
for (int i = 0; i <= max; i++) {
if (str.regionMatches(true, i, searchStr, 0, len)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
System.out.println(containsIgnoreCase("abc", "A"));
System.out.println(containsIgnoreCase("abc", "a"));
System.out.println(containsIgnoreCase("abc", "B"));
System.out.println(containsIgnoreCase("abc", "b"));
System.out.println(containsIgnoreCase("abc", "z"));
System.out.println(containsIgnoreCase("abc", "Z"));
}
}
Output:
true
true
true
true
false
false
If case sensitivity is your only issue convert everything into lowercase
String text = "I love ponies";
String test = "LOVE";
if(text.toLowerCase().contains(test.toLowerCase()))
{
//your code
}
update:
for your code use :
event.getMessage().toLowerCase().contains("douche".toLowerCase())
in all the conditions
You can check twice like this
text.contains(s);
text.contains(s.toLowerCase());
I cant figure out how to start a method to delete a specific entry stored in an array...
I used to do this:
public void deleteEntry() {
SName = JOptionPane.showInputDialog("Enter Name to delete: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, "Found!");
entry[i] = null;
}
}
}
but I was advised not to assign the entry[i] to null because it will ruin my entries...
I have no idea how to code it in another way...
What should I need to do is:
I need to delete a specific entry from an array
please help...
also... its output was error it says:
Exception in thread "main" java.lang.NullPointerException
at AddressBook.viewAll(AddressBook.java:62)
at AddressBook.main(AddressBook.java:36)
Java Result: 1
This is my code in my main program:
public class AddressBook {
private AddressBookEntry entry[];
private int counter;
private String SName;
public static void main(String[] args) {
AddressBook a = new AddressBook();
a.entry = new AddressBookEntry[100];
int option = 0;
while (option != 5) {
String content = "Choose an Option\n\n"
+ "[1] Add an Entry\n"
+ "[2] Delete an Entry\n"
+ "[3] Update an Entry\n"
+ "[4] View all Entries\n"
+ "[5] View Specific Entry\n"
+ "[6] Exit";
option = Integer.parseInt(JOptionPane.showInputDialog(content));
switch (option) {
case 1:
a.addEntry();
break;
case 2:
a.deleteEntry();
break;
case 3:
a.editEntry();
break;
case 4:
a.viewAll();
break;
case 5:
a.searchEntry();
break;
case 6:
System.exit(1);
break;
default:
JOptionPane.showMessageDialog(null, "Invalid Choice!");
}
}
}
public void addEntry() {
entry[counter] = new AddressBookEntry();
entry[counter].setName(JOptionPane.showInputDialog("Enter name: "));
entry[counter].setAdd(JOptionPane.showInputDialog("Enter add: "));
entry[counter].setPhoneNo(JOptionPane.showInputDialog("Enter Phone No.: "));
entry[counter].setEmail(JOptionPane.showInputDialog("Enter E-mail: "));
counter++;
}
public void viewAll() {
String addText = " NAME\tADDRESS\tPHONE NO.\tE-MAIL ADD\n\n";
for (int i = 0; i < counter; i++) {
addText = addText + entry[i].getInfo() + "\n";
}
JOptionPane.showMessageDialog(null, new JTextArea(addText));
}
public void searchEntry() {
int notfound = 0;
SName = JOptionPane.showInputDialog("Enter Name to find: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, entry[i].getInfo2());
break;
} else {
notfound++;
}
}
if (notfound != 0) {
JOptionPane.showMessageDialog(null, "Name Not Found!");
}
notfound = 0;
}
public void editEntry() {
int notfound = 0;
SName = JOptionPane.showInputDialog("Enter Name to edit: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
entry[i] = new AddressBookEntry();
entry[i].setName(JOptionPane.showInputDialog("Enter new name: "));
entry[i].setAdd(JOptionPane.showInputDialog("Enter new add: "));
entry[i].setPhoneNo(JOptionPane.showInputDialog("Enter new Phone No.: "));
entry[i].setEmail(JOptionPane.showInputDialog("Enter new E-mail: "));
break;
} else {
notfound++;
}
}
if (notfound != 0) {
JOptionPane.showMessageDialog(null, "Name Not Found!");
}
notfound = 0;
}
public void deleteEntry() {
SName = JOptionPane.showInputDialog("Enter Name to delete: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, "Found!");
entry[i] = null;
break;
}
}
}
}
Assigning the values to null is going to be the easiest practice. If you're really picky, you could resize the array, but that would be rather pointless. Just keep a separate size counter and decrement it each time you set something to null.
Another reason you're getting a null pointer exception is that you have to consider what's happening when you're replacing values in your array with null but still iterating by counter. You're going to be left with holes in your array upon deletion. The first solution would be to bypass null values altogether, and just shift your array down (somewhat of an expensive operation). The second would be to alter your methods to take those null values into consideration. Example:
public void viewAll() {
String addText = " NAME\tADDRESS\tPHONE NO.\tE-MAIL ADD\n\n";
int nonNull = 0;
for (int i = 0; i < entry.length; i++) {
if (entry[i] != null) {
addText = addText + entry[i].getInfo() + "\n";
nonNull++;
}
if (nonNull == counter) break;
}
JOptionPane.showMessageDialog(null, new JTextArea(addText));
}
I don't have a compiler on this computer, so consider it more of psuedo-code. But the idea is that the counter is only keeping track of how many non-null values you have in your address book, and that these null values could be in random places of your array. I added the nonNull integer as a local counter to keep track of how many values you've encountered that aren't null (so you aren't forced to run through the entire address book). Then, I added the if statement to ensure that the value at entry[i] isn't a null value (trying to invoke getInfo() on a null value is what's giving you that error). Lastly, I added the if statement to break the loop if you've encountered all of the non-null values you have stored. Hope this helps. (Also it may be worth considering a LinkedList to eliminate the null values all together).
Actually, for simplicity's sake, you probably are much better off using a LinkedList, unless you are required to use an array, since you would need to alter all of your methods to take null spaces in your array into account. Assuming you're familiar with LinkedLists of course.
Arrays are immutable. You can change the value for a particular index in the array but you can't change the array size itself. To "delete", you could do:
myArray[index] = null;
And just treat null values as unset/deleted entries.
Assigning to null (currently what you are doing) is the proper thing to do. That will eliminate the reference to the object at that index and allow it to be garbage collected.
Replace entry[i] = null; with this:
System.arraycopy(entry, i + 1, entry, i, counter - i - 1);
--counter;
entry[counter] = null; // optional; helps with garbage collection
--i; // required to not skip the next element
(I'm assuming here that counter is the number of valid entries in entry. This will leave no null entries among the first counter elements of entry (assuming that there weren't any to start with).
Further thought: If you need the array length to always match the number of valid entries, you'll have to re-allocate the array and copy the values over. Just use arraycopy to copy entries from 0 through i-1 and from i+1 to counter-1 into the new array and then assign it to entry. This isn't particularly efficient and is best avoided if possible.
Better to this is List which has remove() method. But if you really want use Array I recommend you change Array to List and then remove all values, after it you can always change List to Array
import javax.swing.JOptionPane;
public class Test {
private static User[] entry = new User[] { new User("Gil"),
new User("Bil"), new User("John") };
public static void main(String... args) {
final Test test = new Test();
test.deleteEntry();
for (int index = 0; index < entry.length; index++) {
User user = entry[index];
if (user != null)
System.out.println(entry[index]);
}
}
public void deleteEntry() {
String SName = JOptionPane.showInputDialog("Enter Name to delete: ");
for (int index = 0; index < entry.length; index++) {
if (entry[index].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, "Found!");
entry[index] = null;
break;
}
}
}
private static class User {
private String name;
public User(String name) {
this.name = name;
}
/**
* #return the name
*/
public String getName() {
return name;
}
#Override
public String toString() {
return name;
}
}
}