Streams: Avoid NullPointerException [duplicate] - java

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I have to get the first element of an array., but it is possible that the element is empty; If the element is empty I put an empty field (I am trying to generate a pdf)
Here is my code now:
public void makePdf(Long id) throws IOException {
Candidacy ca = candidacyRepository.findOne(id);
cos.beginText();
cos.showText(
ca.getInterviews().stream().map(Interview::getAgency).map(Agency::getAgencyName).collect( Collectors.toList()).get(0)!=null?ca.getInterviews().stream().map(Interview::getAgency).map(Agency::getAgencyName).collect( Collectors.toList()).get(0):""));
cos.endText();
}
So I will wish not to prevent the generation of the pdf.
Thank you very much for your support!
UPDATE
Sorry for the lack of precision:
I also sort on the date.
public void makePdf(Long id) throws IOException {
Candidacy ca = candidacyRepository.findOne(id);
cos.beginText();
cos.showText(
ca.getInterviews().stream().sorted((a,b)-> a.getInterviewDate().compareTo(b.getInterviewDate())).sorted((a,f)->f.getInterviewDate().compareTo(a.getInterviewDate())).sorted((b,f)->b.getInterviewDate().compareTo(f.getInterviewDate())).map(Interview::getAgency).map(Agency::getAgencyName).collect( Collectors.toList()).get(0)!=null?ca.getInterviews().stream().sorted((a,b)-> a.getInterviewDate().compareTo(b.getInterviewDate())).sorted((a,f)->f.getInterviewDate().compareTo(a.getInterviewDate())).sorted((b,f)->b.getInterviewDate().compareTo(f.getInterviewDate())).map(Interview::getAgency).map(Agency::getAgencyName).collect( Collectors.toList()).get(0):""));
cos.endText();
}
I get a NullPointerException:/
Thank you for you help

This code doesn't make sense. You are executing the same Stream pipeline twice, and each time you generate an entire List when you only need the first element of that List.
You can use findFirst to get the first element of the Stream.
EDIT :
After testing my original answer, it turned out it doesn't work. findFirst() throws a NullPointerException if the first element is null.
You can avoid that by setting the default value before calling findFirst() :
ca.getInterviews().stream()
.map(Interview::getAgency)
.map(Agency::getAgencyName)
.map(s->s!=null?s:"") // this will replace null with ""
.firstFirst()
.get();

Related

How can I rewrite null checks with optional in a better way [duplicate]

This question already has an answer here:
Java 8 avoiding null pointer checks using Optional
(1 answer)
Closed 1 year ago.
I am having a small snippet of code. I would like to write it in a better way with fewer nested checks. How can I achieve it?
Item item = itemResponse.getItem();
Optional<Item> optionalItem = Optional.ofNullable(item);
if (optionalItem.isPresent()) {
List<NameValue> listValues = item.getValues();
Optional<List<NameValue>> optionalListValues = Optional.ofNullable(listValues);
if (optionalListValues.isPresent()) {
System.out.println(listValues);
}
}
Is there any concise way I can rewrite the above piece of code using Java 8?
You can make itemResponse.getItem() class to return Optional<Item> and use the chained map method which will executed only if Optional has value, and if map method return non null value then only final ifPresent(Consumer consumer) is executed
Optional<Item> item = itemResponse.getItem()
item.map(item::getValues)
.ifPresent(System.out::println);

java.lang.UnsupportedOperationException when trying to delete from an #FXML TableView [duplicate]

This question already has answers here:
java.lang.UnsupportedOperationException for removing a row from the javafx tableview
(2 answers)
Closed 4 months ago.
I don't understand why this method wont work because it worked literally three days ago. Whenever I try to use the method(press the button), The database operations work fine but the program throws an error whenever I try to remove from the actual table view so that the user wont see that row anymore. I added a filtered list to the initialize method and i am concerned that might be the cause of the problem. Here is my code:
Initialize Method:
private void initialize()
{
ObservableList<BloomClient> clients = FXCollections.observableArrayList();
firstNames.setCellValueFactory(new PropertyValueFactory<>("FirstName"));
lastNames.setCellValueFactory(new PropertyValueFactory<>("LastName"));
phoneNumbers.setCellValueFactory(new PropertyValueFactory<>("PhoneNumber"));
birthdays.setCellValueFactory(new PropertyValueFactory<>("Birthday"));
startDates.setCellValueFactory(new PropertyValueFactory<>("StartDate"));
endDates.setCellValueFactory(new PropertyValueFactory<>("ExpireDate"));
try {
clients = dBconnect.getClientList();
} catch (Exception e) {
e.printStackTrace();
}
FilteredList<BloomClient> filteredList = new FilteredList<BloomClient>(clients,b -> true);
filteredSearch.textProperty().addListener(((observable, oldValue, newValue) ->
filteredList.setPredicate(person ->
{
if(newValue == null || newValue.isEmpty())
return true;//nothing in text field
String lowerCaseFilter = newValue.toLowerCase();
if (person.getFirstName().toLowerCase().contains(lowerCaseFilter))
return true;//check first name
else if (person.getLastName().toLowerCase().contains(lowerCaseFilter))
return true;//check last name
else
return false;
})
));
SortedList<BloomClient> sortedList = new SortedList<>(filteredList);
sortedList.comparatorProperty().bind(clientList.comparatorProperty());
clientList.setItems(sortedList);
}
public void freezeAccount() throws SQLException, ParseException {
BloomClient person = clientList.getSelectionModel().getSelectedItem();
dBconnect.sendToFreeze(person);//this works
dBconnect.deleteClient(person);//this works
clientList.getItems().remove(person);//java.lang.UnsupportedOperationException
clientList.refresh();
}
Well, it's just a guess. But it's possible that the clientList is a List<> type that was created using Collections.unmodifiableList(). When you try to modify one of those, an UnsupportedOperationException is thrown.
public static List unmodifiableList(List<? extends T> list)
Returns an unmodifiable view of the specified list. This method allows
modules to provide users with "read-only" access to internal lists.
Query operations on the returned list "read through" to the specified
list, and attempts to modify the returned list, whether direct or via
its iterator, result in an UnsupportedOperationException.
See: https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#unmodifiableList-java.util.List-
Figured it out in a way but would like a deeper explanation. I ended up instead of deleting from the clientList(TableView) I deleted directly from the clients(ObservableList) and made that variable global to be reached by other methods. I'm not sure of the reasoning behind the initial problem.
BloomClient person = clientList.getSelectionModel().getSelectedItem();
dBconnect.deleteClient(person);
clients.remove(person);
clientList.refresh();
}

Java strange issue changing string [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I've tried searching for this, but then I'm not sure when how to describe it.
I have a method that formats some data from a hashmap to go into a mySQL table:
private String valuesList() {
String valuesList = "";
HashMap<String,String> data = getData();
for(Map.Entry<String, String> entry : data.entrySet()) {
String value=entry.getValue();
valuesList+="'"+value+"',";
}
valuesList = valuesList.substring(0, valuesList.length() - 1);
return valuesList;
}
Most of the time that works fine, but in some cases one of the values has an apostrophe in, which leads to an output like this:
'4577314','18-02-2017','null','4566974','null','Overseas Domestic Workers' Rights Bill','1124','null'
Note the 'Overseas Domestic Workers' Rights Bill' bit at the end. I thought that would be easy to fix by changing
valuesList+="'"+entry.getValue()+"',";
to
valuesList+="'"+entry.getValue().replace("'","")+"',";
but the method now throws a null pointer exception at that line. In fact any kind of change to that string such as .trim() does the same, throwing a null.
I'm completely stumped now
You can escape quotes from value like this
value = value.replaceAll("'","''");

Iterator Confused [duplicate]

This question already has answers here:
Calling next on an Iterator once vs multiple times
(3 answers)
Closed 7 years ago.
I had some trouble with the whole iterator concept and for a question in one of my quizzes, I honestly couldn't understand what was up.
public static void main(String[] args)
{
Deque<String> SQ1 = new ArrayDeque<String>();
SQ1.add("Give");
SQ1.add("Me");
SQ1.add("The");
SQ1.add("Best");
SQ1.add("Of");
SQ1.add("Both");
SQ1.add("Worlds");
Iterator<String> It = SQ1.iterator();
while(It.hasNext())
{
if(It.next().equals("Give"))
System.out.print(It.next());
}
}
This is the code, and the question is what will be the output. The correct answer is "Me" when I thought it was "Give". I don't understand how the whole run goes.
This is what I understand:
It does have a next. If that next equals "Give", it will print out that next value. In this case, that value should be "Give", shouldn't it?
Could someone please help me understand this?
The if-statement calls It.next() to check the value, and the the print statement calls It.next() again, rather than printing the value that you just checked.
So what you see will always be the element directly after "Give".
The correct answer is "Me" when I thought it was "Give". I don't understand how the whole run goes.
Right, the code is illustrating a common error. The error is that the code is telling the iterator to advance to the next item and give it to us twice:
Iterator<String> It = SQ1.iterator();
while(It.hasNext())
{
if(It.next().equals("Give"))
// here^^^^^^^^^
System.out.print(It.next());
// and here -------------^^^^^^^^^
}
So it's getting the value, seeing if it's "Give", and then if that value was "Give" it throws it away and gets the next value, which in your test data is "Me". (Note that if "Give" were the last entry, that second call to next would throw an error, since there would be no next entry at that point.)
To "fix" it and have it show "Give", still using that kind of loop, you'd remember the result of the call in a variable, and then use the variable in those two places:
Iterator<String> It = SQ1.iterator();
while(It.hasNext())
{
String value = It.next();
if(value.equals("Give"))
System.out.print(value);
}
But, this is what the enhanced for loop is for: You don't use an It variable at all, just:
for (String value : SQ1) {
if(value.equals("Give"))
System.out.print(value);
}
As you can see from the Java docs:
next
E next()
Returns the next element in the iteration.
Returns:
the next element in the iteration
Throws:
NoSuchElementException - if the iteration has no more elements
So your call:
If(It.next().equals("Give"))
Actually returns the "next" value and sets the Iterator 'It' to the next one in your ArrayDeque.
If you call next again you will be one step further.

Weird behaviour of ArrayList [duplicate]

This question already has answers here:
Why doesn't this code throw a ConcurrentModificationException?
(3 answers)
Closed 7 years ago.
I have following code -
import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1a");
list.add("2b");
for (String s : list) {
list.remove(s);
}
System.out.println("Removed");
System.out.println(list);
}
}
If I run this program, I expect it should throw exception but the output is "2b". If it is running fine then why It is not removing the last object.
Again If I add more element in the list It is thorwing exception java.util.ConcurrentModificationException Which is expected.
My question is -
Why it is not removing all the elements from list if we have 2 elements in the list ??
Why the java.util.ConcurrentModificationException exception occur only when we have more elements ?? I tried a lot of time with two elements.
I am using Java 8.
Thanks in advance.
Actually, when you are removing 1a from the list, the size is getting reduced, and you now have only 1 element in the list, thus the loop does not execute the second time, there by resulting in the keeping the second element.

Categories