Java Catch error and continue running to the next - java

I can't find a way to keep my program running after it catch and error.
For example, I have:
String[] num={"1","2","3","NotNumber","4","5"};
I want to convert all into Integer, so num[3] is invalid, but I want keep running to num[4] and num[5] after it catch the error.
How can I do so?

It would have helped if you had shown what you had tried so far, but the simplest solution is to wrap your int.parse() in a try/catch block and swallow the exception.
for(int i = 0; i < items.length; i++) {
try {
newItems[i] = Itemger.parseInt(items[i]);
catch(Exception ex) {
// do nothing
}
}

Put the try-catch block inside your iteration
JAVA 7
List<Integer> intList = new ArrayList<>();
for(String s : num) {
try {
Integer n = Integer.valueOf(s);
intList.add(n);
} catch (Exception ex) { continue; }
}
JAVA 8 Streams
List<Integer> intList = Arrays.asList(num)
.stream()
.map(s -> {
try {
return Integer.valueOf(s);
} catch(Exception ex) { return null;}
})
.filter(i -> i != null)
.collect(Collectors.toList());

Related

How to display and add tasks to file according to priorities using Java

I need to display/list the contents of a txt file in the ascending order of priority. So, should I need to take a seperate input for priority of task or can I splice the input line?
private static void show() {
String[] items = getData("task.txt");
if (items.length == 0) {
System.out.println("There are no pending tasks!");
} else {
for (int i = items.length - 1; i >=0; i--) {
System.out.printf("[%d] %s\n", i + 1, items[i]);
}
}
My getData looks like this:
private static String[] getData(String file) {
ArrayList<String> dataList = new ArrayList<>();
Scanner s=null;
try {
s = new Scanner(new FileReader(file));
while (s.hasNextLine()){
dataList.add(s.nextLine());
}s.close();
} catch (Exception e) {
System.out.println("Problem to open \"task.txt\".");
} finally {
if (s != null) {
try {
s.close();
} catch (Exception e) {
}
}
}
String[] items = new String[dataList.size()];
for (int i = 0; i < items.length; i++) {
items[i] = dataList.get(i);
}
return items;
}
Input:
10 the thing i need to do
5 water the plants
11 clean house
Output: 5 water the plants
10 the thing i need to do
11 clean house
You can just sort the ArrayList datalist:
(I am assuming that the "priority item" format is already in it)
dataList.sort((o1, o2) -> {
Integer priority1 = Integer.parseInt(o1.split(" ")[0]);
Integer priority2 = Integer.parseInt(o2.split(" ")[0]);
return priority1.compareTo(priority2);
});
Put this right after the try-catch-finally-block.

Using multithreading to read safely from an array that is being written to

I am trying to set up a program that uses a thread to write to an array from a BufferedReader, and another to read from it.
However, if the read result is null (i.e. read index is ahead of write index), I want it to wait, then access the same index again.
I've tried using synchronized statements and read() and notify() like this.
int n = Integer.parseInt(br.readLine());
String[] lines = new String[n];
Thread t1 = new Thread(() -> {
try {
for (int i = 0; i < n; i++) {
synchronized(lines) {
lines[i] = br.readLine();
lines.notify();
}
}
} catch (IOException e) {
return;
}
});
t1.start();
Thread t2 = new Thread(() -> {
try {
int i = 0;
while (i < n) {
String get = lines[i];
if (get == null) {
synchronized (lines) {
lines.wait();
}
continue;
}
add(representString(lines[i]), hmap);
i++;
}
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
});
t2.start();
Problem is, I have a suite of tests that would sometimes freeze, but sometimes work. (I don't have a background in multithreading, I'm just learning from online tutorials to do a non-concurrency assignment faster.)

Java method references that take different numbers of characters?

I'm trying to apply retry logic to a number of methods. For example, I have method1(String) and method2(int, String) that I would like to retry up to a certain number of times.
I would ideally like:
int count = 0;
while (count < MAX_TRIES) {
try {
//run method
} catch (Exception e) {
//increment count
//throw e if count == MAX_TRIES
}
}
inside a method where I could pass in as a parameter method1 or method2. Is there any way to do this? Thanks!
Sure:
public <T> T retry(Callable<T> callable) throws Exception {
int count = 0;
while (true) {
try {
return callable.call();
} catch (Exception e) {
count++;
if (count == MAX_TRIES) {
throw(e);
}
}
}
}
And then
retry(() -> doSomething(a, b));
retry(() -> doSomethingElse(a));
This simple implementation is not very flexible, and could use better exception handling, though. You could use a library to do that (disclaimer: I'm the original author of this library), or at least see how it works and reuse some of its ideas.

List<> - Reflection

I'm trying to determine if a list contains a object, if it does then run a method to clear the original list (in a singleton class), then repopulate the list minus the one I ran the condition over.
public void removeSelectedItem(Object obj){
SearchBuilder builder = SearchBuilder.getInstance();
try {
String methodName = labelToMethod.get(getTitle());
if( methodName == null ){
methodName = getTitle().replace(" ","");
}
Method m = builder.getClass().getMethod("get"+methodName);
Object r = m.invoke(builder);
if( r != null ){
if( r instanceof Integer ){
if( ((Integer) r).intValue() == ((Integer) obj).intValue() ) {
setSelectedItem(null);
}
} else if ( r instanceof String ){
if(r.equals(obj)) {
setSelectedItem(null);
}
} else if ( r instanceof ArrayList ){
Log.d("TEST",((ArrayList) r).size()+"");
if( ((ArrayList) r).contains(obj) ){
Log.d("TEST", "R CONTAINS OBJ");
Log.d("TEST", "BEFORE: " + ((ArrayList) r).size() + "");
clearSelectedItem();
Log.d("TEST","AFTER: " + ((ArrayList) r).size() + "");
for ( int i = 0; i < ((ArrayList) r).size(); i++ ){
Log.d("TEST","IN FOR LOOP" + i);
if( !((ArrayList) r).get(i).equals(obj) ){
Log.d("TEST", "SETTING VALUES");
setSelectedItem(((ArrayList) r).get(i));
}
}
}
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
The clearSelectedItem method is:
public void clearSelectedItem(){
SearchBuilder builder = SearchBuilder.getInstance();
try {
String methodName = labelToMethod.get(getTitle());
if( methodName == null ){
methodName = getTitle().replace(" ","");
}
Method m = builder.getClass().getMethod("clear"+methodName);
m.invoke(builder);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
The output I'm getting is:
D/TEST : 2
D/TEST : R CONTAINS OBJ
D/TEST : BEFORE: 2
D/TEST : AFTER: 0
So it's not entering the loop, as the ArrayList size has been reduced to 0. But what I don't understand is, why has the ArrayList been reduced? Surely the object has been set as part of the m.invoke call earlier in the removeSelectedItem method, and the clearSelectedItem doesn't touch this response?
I'm rather new to Java, so any insight would be great!
EDIT:
So I've managed to solve my problem, but would still really like some insight into what's going on...
I've solved it by cloning the ArrayList:
} else if ( r instanceof ArrayList ){
Object c = ((ArrayList) r).clone();
if( ((ArrayList) c).contains(obj) ){
clearSelectedItem();
for ( int i = 0; i < ((ArrayList) c).size(); i++ ){
if( !((ArrayList) c).get(i).equals(obj) ){
setSelectedItem(((ArrayList) c).get(i));
}
}
}
}
So I dont understand why you are repopulating the list itself,
would it be much cleaner or neat if you just use
if(list.contain(object))
{
list.remove(object);
}
or if you want to remove all of them just use
while(list.contain(object))
{
list.remove(object);
}
So after a little more research, Java is pass-by-value, which means that it passes the reference to the ArrayList, rather than create a new ArrayList with the same values. Amending Object r in any way affects the original ArrayList in SearchBuilder itself.
http://www.javaranch.com/campfire/StoryPassBy.jsp

Exhausted Resultset when calling a method inside the while(rset.next)

I'm getting an Exhausted resultset form the following code.
I've tried a few different things now and can't find a solution,
if I don't call the songs method it works, but the songs method works when it's called, can't get my head around it, hoping I'm missing something simple.
public void refreshList() {
rset = po.getProduct();
if (plist.size() > 0) {
for (int i = plist.size() - 1; i >= 0; i--) {
plist.remove(i);
}
}
try {
while (rset.next()) {
songs(rset.getString(1));
CD c = new CD(alist);
Product p = new Product(rset.getString(1),
rset.getString(2),
rset.getString(3),
rset.getDouble(4),
rset.getDouble(5),
rset.getInt(6),
rset.getString(7),
rset.getString(8),
rset.getString(9),
rset.getDouble(10), c);
plist.add(p);
}
} catch (Exception ex) {
System.out.println(ex);
}
}
public void songs(String ID)
{
rset = po.getSongs();
alist = new ArrayList<Song>();
try {
while (rset.next()){
Song s = new Song(rset.getString(1),
rset.getString(2),
rset.getString(3));
slist.add(s);
}
}
catch (Exception ea) {
System.out.println(ea);
}
for(int i = 0; i < slist.size(); i++)
{
if(slist.get(i).getSong_id().equals(ID))
{
alist.add(slist.get(i));
}
}
}
Inside refreshList you have while (rset.next()) loop, on each iteration of it you have songs(rset.getString(1));, which itself has while(rset.next(). This leads to result set exhaustion, because when you return from songs() you try to take some more data from the current position of result set, while in songs() you got out of while (rset.next()) loop, i.e. retrieved all its rows. Consider refactoring your code to avoid nested loops based on result set.

Categories