I have this code...
Donor newDonor = new Donor(null,
donor.getName().split(" ")[0],
donor.getName().split(" ")[1],
address);
The problem is I am not allowed to change donor to have separate fields of first name and surname. So now the above code requires a surname. What if they don't enter it. Shall I do an if statement, if so how? Or is there a way to define a default value. So if they don't enter a surname, the default is nothing (""). Please advice.
String[] names = donor.getName().split(" ");
String first = names[0];
String last = names.length > 1? names[1] : "";
Donor newDonor = new Donor(null, first, last, address);
If for whatever reasons you want the check in params of constructor
Donor newDonor = new Donor(null,
donor.getName().split(" ")[0],
donor.getName().split(" ").length >1 ? donor.getName().split(" ")[1]: "",
address);
You can add a space at the end, and care about it (-1 in split function) in case there is only one word
String[] names = (fullName + " ").split("\\s+", -1);
Donor newDonor = new Donor(null, names[0], names[1], "address");
How about to create a sort of adapter class to do the dirt work. Something like this:
public class DonorAdapter {
private static final String DEFAULT_NAME = "xyz";
private static final String DELIMITER = " ";
private String name;
private String surnameName;
public DonorAdapter(Donor donor) {
String[] s = donor.getName().split(DELIMITER);
name = s.length - 1 >= 0 ? s[0] : DEFAULT_NAME;
surnameName = s.length - 1 >= 1 ? s[1] : DEFAULT_NAME;
}
public String getName() { return name; }
public String getSurname() { return surnameName; }
}
Then your code would be simpler and IMO more elegant.
DonorAdapter adapter = new DonorAdapter(donor);
Donor newDonor = new Donor(null, adapter.getName(), adapter.getSurname(), address);
Related
I am making a while loop that asks for a name and an id and adds it to an ArrayList repeatedly until told to stop for my computer science class. How could I get the name of the new "TeamMember" to change every time? Also, would that even work and if not why and how could I get it to work?
This is my code (Main):
import java.util.ArrayList;
import java.util.Scanner;
public class TeamClassMain {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ArrayList <TeamMember> list = new ArrayList();
String name;
String id;
String ArrayVar;
int number = 0;
int stop = 0;
while (stop == 0) {
System.out.println("Enter the next name:");
name = scan.nextLine();
name = name.toLowerCase();
if (name == "stop") {
stop = 1;
}
System.out.println("Enter the next ID:");
id = scan.nextLine();
ArrayVar = "member " + number;
TeamMember member1 = new TeamMember(name, id);
number++;
}
}
}
This isn't necessary, but it might be interesting to know what TeamMember is so this is my TeamMember class:
import java.lang.*;
public class TeamMember {
String fullName;
String idString;
TeamMember(String name, String id) {
name = name.toUpperCase();
char character;
String string;
int num;
for (int i = 0; i < name.length() - 1; i++) {
if (i == 0) {
character = name.charAt(0);
string = "" + character;
string = string.toUpperCase();
character = string.charAt(0);
i = character;
}
if (name.charAt(i) == ' ') {
character = name.charAt(i + 1);
string = "" + character;
string = string.toUpperCase();
character = string.charAt(i + 1);
name.substring(i + 1, character);
}
}
fullName = name;
idString.valueOf(id);
}
public String toString() {
return fullName;
}
int compareTo(TeamMember other) {
return idString.compareTo(other.idString);
}
}
Step 1 - Don't use a hammer to drive screws.
Specifically,
pay attention to the input data: you are asking the user to enter a map value between a name and an id.
It appears that the name is the key and the id is the value.
Store map "stuff" in a Map.
Step 2 - The TeamMember class provides just about 0 value. Just use the map between name and id.
In a less toy problem, TeamMember would do more that map between name and id.
In that case,
determine which is the appropriate key (id or name) and allocate (use new) a new TeamMember as the value each time you insert into the Map.
you need to add TeamMember to ArrayList
TeamMember member1 = new TeamMember(name, id);
list.add(member1);//add to list
you should break the while loop after stop that stop not gonna add in list
and use equal for comparing the string
if (name.equals("stop")) {
stop = 1;
break;
}
in the following code, I have a method which is supposed to take data from a text file (lastname, firstname, classname) and tell whether the student was present or not (attendance), then populate a table with the value of "only" students present a certain number of times (basically present less than the times specified by input into a textfield). I tried using a hashmap, but am unsure as to where to put the "put" statement(s) in order to populate the hashmap correctly. I get repeats of information in the table and I do not want duplicates. My code is as follows: Any help would be greatly appreciated.
public void processFile() throws FileNotFoundException{
DefaultTableModel model = (DefaultTableModel) this.jTable_areasOfConcern.getModel();
File g = new File("pupilSortTemp.txt");
InputStream is;
Scanner scan = null;
HashMap<Integer, String> attendanceList = new HashMap<>();
try {
String firstName;
String lastName;
String className;
String studentKey;
String tab = "\t";
String attendance;
int attendanceCount = 0;
int totalDaysOrLessStudentsPresent;
totalDaysOrLessStudentsPresent = Integer.valueOf(this.jTextField_totalDays.getText());
is = new FileInputStream(g);
scan = new Scanner(is);
String[] array;
String line = scan.nextLine();
if (line.contains(tab)) {
array = line.split(tab);
}
else {
array = line.split("\n");
}
firstName = array[0];
lastName = array[1];
className = array[2];
attendance = array[4];
System.out.println("firstName=" + firstName);
System.out.println("lastName=" + lastName);
System.out.println("className=" + className);
System.out.println("attendance=" + attendance);
if (attendance.equals("Present")){
attendanceCount++;
studentKey = firstName + tab + lastName + tab + className;
attendanceList.put(attendanceCount, studentKey);
System.out.println("attendanceCountIfPresent=" + attendanceCount);
}
System.out.println("attendanceCountIfNotPresent=" + attendanceCount);
while (scan.hasNextLine()) {
line = scan.nextLine();
if (line.contains(tab)) {
array = line.split(tab);
}
else {
array = line.split("\n");
}
System.out.println("array0=" + array[0]);
System.out.println("array1=" + array[1]);
System.out.println("array2=" + array[2]);
System.out.println("array4=" + array[4]);
if (array[0].equals(firstName) && array[1].equals(lastName)){
if (array[4].equals("Present") && (attendanceCount < totalDaysOrLessStudentsPresent)){
attendanceCount++;
//studentKey = firstName + tab + lastName + tab + className;
//attendanceList.put(attendanceCount, studentKey);
System.out.println("attendanceCountIfPresent==" + attendanceCount);
model.addRow(new Object[]{array[2], array[1], array[0], attendanceCount, true});
}
}else {
if (array[4].equals("Present") && (attendanceCount < totalDaysOrLessStudentsPresent)){
attendanceCount = 1;
System.out.println("attendanceCountIfPresent++=" + attendanceCount);
firstName = array[0];
lastName = array[1];
className = array[2];
attendance = array[4];
model.addRow(new Object[]{array[2], array[1], array[0], attendanceCount, true});
studentKey = firstName + tab + lastName + tab + className;
attendanceList.put(attendanceCount, studentKey);
}
else {
attendanceCount = 0;
}
}
//attendanceList.put(attendanceCount, studentKey);
}//end while
for (Map.Entry<Integer, String> entry : attendanceList.entrySet()) {
studentKey = entry.getValue();
attendanceCount = entry.getKey();
array = studentKey.split(tab);
model.addRow(new Object[]{array[2], array[1], array[0], attendanceCount, true});
}
}catch (FileNotFoundException e){
}
finally{
if(scan != null){
scan.close();
}
}
}
I don't think that I'd use a HashMap as you're doing it, and if I did, the attendance count certainly would not be used as the key field for the map. All this will do is guarantee that only one student with that attendance count is entered into the collection. Create a Student class, give it the needed fields, including name, perhaps studentId, and yes, attendanceCount, and create a collection of that, perhaps an ArrayList<Student>. Then if you wanted to sort it, you could use a Comparator that sorted the attendanceCount values, or if you wanted to filter it, you could filter it using the same field's value.
Also, I'd have my Student class override equals and hashCode, and would use invariant fields for these methods, and most definitely not the attendance field. If the Student already exists in the ArrayList, by calling contains(student) on the List, then I'd increment the attendance of that student. Otherwise I'd add a new Student to the List.
If you have to use a HashMap, then you would reverse your key and value fields, i.e., have it as a HashMap<Student, Integer> where the value is the attendance count. Again for this to work Student would need to have its equals and hashCode methods overridden using an invariant field or fields within these methods, such as studentID.
I have string for instance, "John Daws Black" splitted with spaces and I need to split them to two parts so that there will be name part like "John Daws" and surname part like "Black". However the front name part can be any length like "John Erich Daws Black". My code can get the last part:
public String getSurname(String fullName){
String part = "";
for (String retval: fullName.split(" "))
part = retval;
return part;
}
But I don't know how to get the front part.
Just find the last space, then manually split there using substring().
String fullName = "John Erich Daws Black";
int idx = fullName.lastIndexOf(' ');
if (idx == -1)
throw new IllegalArgumentException("Only a single name: " + fullName);
String firstName = fullName.substring(0, idx);
String lastName = fullName.substring(idx + 1);
Try this.
public String getName(String fullName){
return fullName.split(" (?!.* )")[0];
}
public String getSurname(String fullName){
return fullName.split(" (?!.* )")[1];
}
Below methods worked for me. It takes into account that if middle name is present, then that gets included in first name:
private static String getFirstName(String fullName) {
int index = fullName.lastIndexOf(" ");
if (index > -1) {
return fullName.substring(0, index);
}
return fullName;
}
private static String getLastName(String fullName) {
int index = fullName.lastIndexOf(" ");
if (index > -1) {
return fullName.substring(index + 1 , fullName.length());
}
return "";
}
Get the last element of the array after spliting it:
String fullName= "John Daws Black";
String surName=fullName.split(" ")[fullName.split(" ").length-1];
System.out.println(surName);
Output:
Black
Edit:
for the front part, use substring:
String fullName= "John Daws Black";
String surName=fullName.split(" ")[fullName.split(" ").length-1];
String firstName = fullName.substring(0, fullName.length() - surName.length());
System.out.println(firstName );
Output:
John Daws
//Split all data by any size whitespace
final Pattern whiteSpacePattern = Pattern.compile("\\s+");
final List<String> splitData = whiteSpacePattern.splitAsStream(inputData)
.collect(Collectors.toList());
//Create output where first part is everything but the last element
if(splitData.size() > 1){
final int lastElementIndex = splitData.size() - 1;
//connect all names excluding the last one
final String firstPart = IntStream.range(0,lastElementIndex).
.mapToObj(splitData::get)
.collect(Collectors.joining(" "));
final String result = String.join(" ",firstPart,
splitData.get(lastElementIndex));
}
Just a re-write for Andreas answer above but using sperate methods to get first and last name
public static String get_first_name(String full_name)
{
int last_space_index = full_name.lastIndexOf(' ');
if (last_space_index == -1) // single name
return full_name;
else
return full_name.substring(0, last_space_index);
}
public static String get_last_name(String full_name)
{
int last_space_index = full_name.lastIndexOf(' ');
if (last_space_index == -1) // single name
return null;
else
return full_name.substring(last_space_index + 1);
}
Here's a solution I've used before that accounts for suffixes too.. ( 3 chars at the end )
/**
* Get First and Last Name : Convenience Method to Extract the First and Last Name.
*
* #param fullName
*
* #return Map with the first and last names.
*/
public static Map<String, String> getFirstAndLastName(String fullName) {
Map<String, String> firstAndLastName = new HashMap<>();
if (StringUtils.isEmpty(fullName)) {
throw new RuntimeException("Name Cannot Be Empty.");
}
String[] nameParts = fullName.trim().split(" ");
/*
* Remove Name Suffixes.
*/
if (nameParts.length > 2 && nameParts[nameParts.length - 1].length() <= 3) {
nameParts = Arrays.copyOf(nameParts, nameParts.length - 1);
}
if (nameParts.length == 2) {
firstAndLastName.put("firstName", nameParts[0]);
firstAndLastName.put("lastName", nameParts[1]);
}
if (nameParts.length > 2) {
firstAndLastName.put("firstName", nameParts[0]);
firstAndLastName.put("lastName", nameParts[nameParts.length - 1]);
}
return firstAndLastName;
}
Try this :
String[] name = fullname.split(" ")
if(name.size > 1){
surName = name[name.length - 1]
for (element=0; element<(name.length - 1); element++){
if (element == (name.length - 1))
firstName = firstName+name[element]
else
firstName = firstName+name[element]+" "
}
}
else
firstName = name[0]
so first here is my code :
public class eol {
public static void main(String[] args) {
String x = "Charles.Baudelaire*05051988*France Sergei.Esenin*01011968*Russia Herman.Hesse*23051996*Germany";
String[] word= x.split("[.,*, ]");
for(int i=0;i<word.length;i++){
// System.out.print(word[i]+" ");
}
String name = word[0];
String lastname = word[1];
String dod =word[2];
String cob= word[3];
System.out.print("First person data : "+
"\n"+ name +" "+ "\n"+lastname+" "+"\n"+ dod+" "+"\n"+ cob);
I want to loop through string x, and take needed values, and use them to make 3 objects of class writer, is there any way i do this with for loop ?
Or would i have to "break" original string in 3 smaller arrays, then do for loop for every one of them.
I mean, i can use for loop to print out data on screen, by incrementing counter by certain value, how ever to add these data to fields is something I don't understand how to do.
Sure. You can do the following:
Validate.isTrue(word.length % 4 == 0, "Array size must be a multiple of 4");
List<Writer> writers = new ArrayList<>();
for (int i=0; i<word.length; i+=4) {
String name = word[i];
String lastname = word[i+1];
String dod =word[i+2];
String cob= word[i+3];
writers.add(new Writer(name, lastname, dod, cob));
}
i += 4 instead of i++ after each tern of loop, and use word[i], word[i+1], word[i+2] and word[i+3] in loop.
i.e.
String x = "Charles.Baudelaire*05051988*France Sergei.Esenin*01011968*Russia Herman.Hesse*23051996*Germany";
String[] word= x.split("[.,*, ]");
for(int i=0;i<word.length;i+=4){
String name = word[i];
String lastname = word[i+1];
String dod =word[i+2];
String cob= word[i+3];
// Use these variable.
}
I cannot figure out how to change the order of a given name.
For example: Van-Dame Claud
Result: Claud Dame-Van
I created this method, but it seems that is not correct, any suggestion or maybe a better method?
public String NameInvers(){
String Name, Name = null, Name = null, NameFinal;
int s1 = getName().indexOf(' ');
int s2 = getName().indexOf('-');
if(s1 != 0){
Name1 = getName().substring(0, s1);
if(s2 != 0)
{
Name2 = getName().substring(s1, s2);
Name3 = getName().substring(s2);
}
NameFinal = Name3 + Name2 + Name1;
}
else
NameFinal = getName();
return NameFinal;
}
Edit: In my Main method I have a number of names. The thing is that it says: throw new StringIndexOutOfBoundsException(subLen) and it won't show up.
Here you go:
public static String reverseName (String name) {
name = name.trim();
StringBuilder reversedNameBuilder = new StringBuilder();
StringBuilder subNameBuilder = new StringBuilder();
for (int i = 0; i < name.length(); i++) {
char currentChar = name.charAt(i);
if (currentChar != ' ' && currentChar != '-') {
subNameBuilder.append(currentChar);
} else {
reversedNameBuilder.insert(0, currentChar + subNameBuilder.toString());
subNameBuilder.setLength(0);
}
}
return reversedNameBuilder.insert(0, subNameBuilder.toString()).toString();
}
Test:
public static void main(String[] args) {
printTest("Van-Dame Claud");
printTest("Victor Hugo");
printTest("Anna");
printTest("");
}
private static void printTest(String S) {
System.out.printf("Reverse name for %s: %s\n", S, reverseName(S));
}
Output:
Reverse name for Van-Dame Claud: Claud Dame-Van
Reverse name for Victor Hugo: Hugo Victor
Reverse name for Anna: Anna
Reverse name for :
First of all, you duplicate your variable Name declaration, three times. I suppose that you want to put:
String Name1, Name2 = null, Name3 = null, NameFinal;
instead of:
String Name, Name = null, Name = null, NameFinal;
Then, if you just have 2 names with a - in the middle and you want to change their order you can use split function to separate it, finding where - is. You can use it like this:
String string = "Van-Dame Claud";
String[] divide = string.split("-");
String Name1 = divide[0];
String Name2 = divide[1];
String result = Name2 + "-" + Name1;
EDIT: Name1 will be Van and Name2 will be Dame Claud so the result will be Dame Cloud-Van.
I expect it works for you!
You want to have a method to convert all names or just the the names in form of Name-Name Name? I'm assuming you want a method for all names. Since if you just want to reverse names in this specific form, there is no meaning for you to check value of s1 and s2, you know s1 and s2 must be a positive number. If you check because you want to do error checking, then you should throw an exception if the name is not in the form you want. If you want to do it for all names, below is the pseudocode, you can implement it yourself (your code contains several errors, you are using Name1, Name2, Name3, but you never declared them and duplicate variable Name declaration):
string finalName = ""
string [] strs1 = name split by " "
foreach str1 in strs1
string [] strs2 = str1 split by "-"
foreach str2 in strs2
if str2.first?
finalName = str2 + " " + finalName
else
finalName = str2 + "-" + finalName
end
end
end
return finalName.substring 0, finalName.length-1 //remove the space at the end
I think this would work. Hope you find it useful.