public class SomeClass {
int[] table;
int size;
public SomeClass(int size) {
this.size = size;
table = new int[size];
}
public static void main(String[] args) {
int[] sizes = {5, 3, -2, 2, 6, -4};
SomeClass testInst;
for (int i = 0; i < 6; i++) {
testInst = new SomeClass(sizes[i]);
System.out.println("New example size " + testInst.size);
}
}
}
When the constructor SomeClass is called with an argument of -2, a run time error will be generated: NegativeArraySizeException.
I am looking to modify this code so that it behaves more robustly by using try, catch and throw. The constructor should throw an exception but otherwise do nothing when called with a non-positive argument. The main method should catch the exception and print a warning message then continue execution through all six iterations of the loop.
Somebody point me in the right direction ?
You need to throw an exception (preferably IllegalArgumentException) from your constructor of SomeClass whenever you get a negative number and handle it in your main method.
Your code should look like;
public class SomeClass
{
int[] table;
int size;
public SomeClass(int size)
{
if ( size < 0 )
{
throw new IllegalArgumentException("Negative numbers not allowed");
}
this.size = size;
table = new int[size];
}
public static void main(String[] args)
{
int[] sizes = { 5, 3, -2, 2, 6, -4 };
SomeClass testInst;
for (int i = 0; i < 6; i++)
{
try
{
testInst = new SomeClass(sizes[i]);
System.out.println("New example size " + testInst.size);
}
catch (IllegalArgumentException e)
{
System.out.println(e.getMessage());
}
}
}
}
There are operations, like connecting to a remote server using a Socket, which can throw exceptions like SocketException. You need to catch and deal with those exceptions because before you aptempt the connection there is no way to know if it is going to suceed or not.
NegativeArrayException is not like that. Before aptempting to create the array you can know for sure that it is going to fail if you use a negative size.
If the size comes from your code, as is the case, you should fix your code rather than catching that exception.
If it comes from any input you should verify that input and act acordingly before trying to create the array.
Assuming your array of sizes is actually a simplified example of input the way to deal with it would be :
public class SomeClass {
int[] table;
int size;
public SomeClass(int size) {
this.size = size;
table = new int[size];
}
public static void main(String[] args) {
int[] sizes = {5, 3, -2, 2, 6, -4};
SomeClass testInst;
for (int i = 0; i < 6; i++) {
if (sizes[i] < 0) {
System.out.println("Warning");
} else {
testInst = new SomeClass(sizes[i]);
System.out.println("New example size " + testInst.size);
}
}
}
}
Which gives as output :
New example size 5
New example size 3
Warning
New example size 2
New example size 6
Warning
Related
I was able to make the Constructor and capacity methods to works but don;t know why size(),isFull() and isEmpty() fails.I believe its pretty simple but i am just unable to see a minor error and fix it.Hope someone can clarify what i am doing wrong with thorough explaination.Also,my constructor works with the test file and it passes,but just want to know Is my constructor correct as specified by question?
import java.util.Arrays;
import java.util.Iterator;
public class SortedArray<T extends Comparable> implements
java.lang.Iterable<T> {
public SortedArray(int capacity) {
this.array = (T[]) new Comparable[0];
this.capacity = capacity;
this.size = 0;
}
public SortedArray(int capacity, T[] data) {
if(capacity > data.length)
{
this.capacity = capacity;
}
else {
this.capacity = data.length;
}
this.size = data.length;
this.array = (T[]) new Comparable[0];
}
final public int size() {
return this.size
}
final public int capacity() {
return this.capacity;
}
final boolean isEmpty() {
return size == 0;
}
final boolean isFull(){
return size == capacity;
}
#Override
final public Iterator<T> iterator() {
// Do not modify this method.
return Arrays.stream(array).iterator();
}
// Do not modify these data members.
final private T[] array; // Storage for the array's element
private int size; // Current size of the array
final private int capacity; // Maximum size of the array
}
//// Test File:
#Test
public void testConstructor() {
System.out.println("Constructors");
SortedArray array = new SortedArray(20);
assertEquals(array.size(), 0);
assertEquals(array.capacity(), 20);
Integer[] data = {1, 2, 3, 4};
array = new SortedArray(20, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 20);
array = new SortedArray(2, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 4);
}
#Test
public void testSize() {
System.out.println("size");
SortedArray arr = new SortedArray(10);
// Array is initially empty
assertEquals(arr.size(), 0);
// Inserting elements increases size
arr.add(12);
arr.add(13);
arr.add(14);
assertEquals(arr.size(), 3);
// Inserting duplicates increases size
arr.add(12);
arr.add(13);
assertEquals(arr.size(),5);
// Fill up the array
for(int i = 0; i < 5; ++i)
arr.add(i);
assertEquals(arr.size(), 10);
// Size does not change when array is full
arr.add(10);
arr.add(11);
assertEquals(arr.size(), 10);
// Removing elements decreases size
arr.remove(0);
arr.remove(1);
arr.remove(2);
assertEquals(arr.size(), 7);
// but removing elements that don't exist doesn't change anything
arr.remove(100);
assertEquals(arr.size(), 7);
// Removing from the empty array doesn't change size.
SortedArray empty = new SortedArray(10);
empty.remove(10);
assertEquals(empty.size(), 0);
}
#Test
public void testCapacity() {
System.out.println("capacity");
SortedArray array = new SortedArray(20);
assertEquals(array.capacity(), 20);
array = new SortedArray(100);
assertEquals(array.capacity(), 100);
Integer[] data = {1,2,3,4,5,6,7,8,9,0};
array = new SortedArray(20, data);
assertEquals(array.capacity(), 20);
array= new SortedArray(5, data);
assertEquals(array.capacity(), 10);
}
#Test
public void testIsEmpty() {
System.out.println("isEmpty");
SortedArray array = new SortedArray(10);
assertTrue(array.isEmpty());
array.add(10);
assertFalse(array.isEmpty());
array.remove(10);
assertTrue(array.isEmpty());
}
#Test
public void testIsFull() {
System.out.println("isFull");
SortedArray array = new SortedArray(5);
assertFalse(array.isFull());
array.add(10);
array.add(11);
array.add(12);
array.add(13);
array.add(14);
assertTrue(array.isFull());
array.remove(10);
assertFalse(array.isFull());
}
#Test
public void testIterator() {
}
testSize Failed : Expected <0> but was <3>
testCapacity Failed : Expected <5> but was <10>
testConstructor Failed : Expected <0> but was <4>
testisFull Failed : jUnit.framework.AssertionFailedError
testisEmpty Failed : jUnit.framework.AssertionFailedError
You forgot to include your "add(T toAdd)" and "remove(T toRemove)" methods, which when I was going through to make the tests pass, was the source of a vast majority of the fails. (Note: a trace of the fails would help, since your adds and removes need to be pretty complicated to fit the design it seems you intend)
Anyways, on to fixing what I can see.
In your second constructor, you never actually assign the data you take in. You call this.array = (T[]) new Comparable[0]; which creates an empty array of type Comparable. In reality, you need to call this.array = data in order to keep what's been given to you.
Another thing, in your size() method you forgot to place a semicolon after this.size. That tends to prevent things from passing.
Finally, final private T[] array can't have final, or you'll never be able to add or remove elements.
As a bonus, here are the add() and remove() methods I used to fit the requirements and make the tests pass (with comments!!!!):
public void add(T t) {
if (!(size >= capacity)) { //If there's room...
if (size == 0) //If the array is empty...
array[0] = t; //Add to first index
else
array[size] = t; //Add to next available index
size++;
}
}
public void remove(T element) {
if (size <= 0) //If the array is empty...
return; //Stop here
else {
for (int i = 0; i <= this.size(); i++) { //Linear search front-to-back
if (array[i].equals(element)) { //Find first match
array[i] = null; //Delete it
size--;
if (i != size) { //If the match was not at the end of the array...
for (int j = i; j <= (this.size() - 1); j++)
array[j] = array[j + 1]; //Move everything after the match to the left
}
return; //Stop here
}
}
}
}
On a side note, your calls to create SortedArray objects should really be parameterized (Using the <> such as SortedArray<Integer> arr = new SortedArray<Integer>(5, data);).
I am new to this programming world. I tried to print length of the array without using predefined functions.
But when i run my code i am getting Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
can someone please help me to find out the bug
Here is my code.
public class Arraylen {
public static void main(String[] args) {
int[] ary = {1, 3, 4, 5, 68, 9};
int len;
for(len = 1; ary[len] != '\0'; len++) {
System.out.println(len);
}
}
}
What is wrong with using ary.length? .length is a property and not a function. You would not be coding ary.length(), let alone that "function" doesn't even exist.
public class StackOverflow {
public static void main(String args[]) {
int[] ary = {1, 3, 4, 5, 68, 9};
System.out.println(ary.length);
}
}
Result:
6
Just use an enhanced for loop:
public class Arraylen
{
public static void main(String[] args)
{
int[] ary = {1,3,4,5,68,9};
int len = 0;
for(int number : ary)
{
len++;
}
System.out.println(len);
}
}
This iterates over every item in the array, without you having to worry that the index will go over the array size.
You could also use a while loop with a try-catch block to find the length.
Something like this:
boolean lengthFound = false;
int length = 0;
while (!lengthFound) {
try {
// This line throws an Exception when length is equal to the length of the array
int notImportant = array[length] + 2;
length++;
}
// This prevents the exception from breaking anything and gets you out of the
// loop
catch (ArrayOutOfBoundsException ex) {
lengthFound = true;
}
}
// At this point array.length == length
I try to analyze runtime information with reflections. The class I try to analyze has a static array of type me.instrumentor.InstrumentStackElem and I want to access and copy it using reflections.
The code looks like this:
final Field stack = this.object.getClass().getDeclaredField("ise_array");
stack.setAccessible(true);
final Object arr = stack.get(null);
final InstrumentStackElem[] tmp = new InstrumentStackElem[Array.getLength(arr)];
for (int i = 0; i < tmp.length; i++) {
tmp[i] = (InstrumentStackElem) Array.get(arr, i);
}
When I try to run it, I get java.lang.ClassCastException: me.instrumentor.InstrumentStackElem cannot be cast to me.instrumentor.InstrumentStackElem at the line in the for loop.
Can anyone help me?
If it's sufficient for you to work on raw objects, you can try this solution. It enables you to work with arbitrary types and further you don't have to worry about different class loaders. A properly implemented toString() would be helpful too, I guess.
import java.lang.reflect.Array;
import java.lang.reflect.Field;
public class Main {
#SuppressWarnings("unused")
private static Integer[] targetArray = new Integer[] { 0, 1, 2, 3, 4, 5 };
public static void main(String[] args) throws Exception {
Field arrayMember = Main.class.getDeclaredField("targetArray");
arrayMember.setAccessible(true);
Object array = arrayMember.get(null);
int length = Array.getLength(array);
// get class of array element
Class<? extends Object> elementType = array.getClass().getComponentType();
Object copy = Array.newInstance(elementType, length);
for (int i = 0; i < length; i++) {
Array.set(copy, i, Array.get(array, i));
}
// if you know the type, you can cast
if (Integer[].class.isInstance(copy)) {
System.out.println("Integer[].class.isInstance(copy) == true");
Integer[] copiedArray = Integer[].class.cast(copy);
for (Integer i : copiedArray)
System.out.println(i);
} else {
for (int i = 0; i < length; i++) {
System.out.println(Array.get(copy, i));
}
}
}
}
OUTPUT
Integer[].class.isInstance(copy) == true
0
1
2
3
4
5
I have this code which is to check in the two arrays and print out the values that dont exist in the other array. I think the way i did it is not the most efficient way to do it hence can anyone offer a better OOP way to write this code in Java?
Thanks
public class Calculate {
static int [] x = {1,2,4,6,7};
static int [] y = {2,3,4,6,7};
static boolean xflag = true;
static boolean yflag = true;
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i = 0; i<x.length; i++)
{
for (int b=0; b<y.length; b++)
{
if(x[i]!= y[b])
{
xflag= false;
}
else
{
xflag = true;
break;
}
}
if(xflag==false)
{
System.out.println(x[i] +" does not exist in array 2");
}
}
for(int i = 0; i<x.length; i++)
{
for (int b=0; b<y.length; b++)
{
if(y[i]!= x[b])
{
yflag= false;
}
else
{
yflag = true;
break;
}
}
if(yflag==false)
{
System.out.println(y[i] +" does not exist in array1");
}
}
}
}
Using Collection class removeAll method
String original[] = { "1","2","3","4","6"};
String testStr[] = { "1","2","3","5","7" };
List origList = new ArrayList(Arrays.asList(original));
List testList = new ArrayList(Arrays.asList(testStr));
System.out.println(origList.removeAll(testList));
System.out.println(origList);
you can use java collection framework, Many function are there,
here is simple example check it.
public static void main(String a[]){
List<String> sl = new ArrayList<String>();
sl.add("apple");
sl.add("java");
sl.add("c++");
sl.add("unix");
sl.add("orange");
sl.add("airtel");
List<String> tl = new ArrayList<String>();
tl.add("job");
tl.add("oracle");
tl.add("jungle");
tl.add("cricket");
boolean isCommon = Collections.disjoint(sl,tl);
System.out.println("Does not found any common elements? "+isCommon);
tl.add("java");
isCommon = Collections.disjoint(sl,tl);
System.out.println("Does not found any common elements? "+isCommon);
}
You may use Apache's CollectionUtils for this purpose if you want an abstraction from the implementation logic.E.g:
public static void main(String[] args) {
List<Integer> list1=Arrays.asList(1,2,4,6,7);
List<Integer> list2=Arrays.asList(2,3,4,6,7);
System.out.println(CollectionUtils.disjunction(list1,list2));
}
You can code this way
List<Integer> array1 = Arrays.asList(1,2,4,6,7);
List<Integer> array2 = Arrays.asList(2,3,4,6,7);
List<Integer> disjointArray = new ArrayList<Integer>();
for (Integer value : array1) {
if (!array2.contains(value)) {
disjointArray.add(value);
}
}
And then you can print disjointArray or do whatever manipulation you want.
Here a running example using Javas Collection classes:
public class Disjunction {
public static void main(String args[]) throws UnsupportedEncodingException {
//Some data preparation
List<Integer> list1=Arrays.asList(1,2,4);
List<Integer> list2=Arrays.asList(5,2,8);
//Here calculating data1-data2 and data2-data1, collect all list items
//that are in data1 or in data2 but not in both.
List<Integer> data1 = new ArrayList<>(list1);
data1.removeAll(list2);
List<Integer> data2 = new ArrayList<>(list2);
data2.removeAll(list1);
//Merging both results. data1 contains now exclusive or of list1 and list2
data1.addAll(data2);
System.out.println("exclusive or is " + data1);
}
}
It prints out
exclusive or is [1, 4, 5, 8]
Try the following program that checks two arrays for numbers they both have and numbers they don't have:
package test;
import java.util.ArrayList;
public class ArrayDifferentiater {
public static void main(String[] args) {
int[] ori = { 1, 5, 4, 8, 6, 65, 16, 6, 575, 64, 561, 57, 57 };
int[] che = { 1, 4, 8, 6 };
sort(ori, che);
}
public static void sort(int[] a, int[] b) {
/**
* 'foundNum' contains the numbers which exists in both array.
* 'notFoundNum' contains the numbers which exists in only first array.
*/
ArrayList<Integer> foundNum = new ArrayList<>();
ArrayList<Integer> notFoundNum = new ArrayList<>();
// First for loop starts
for (int i = 0; i < a.length; i++) {
// Second for loop starts
for (int j = 0; j < b.length; j++) {
/**
* Check if array 1 contains value of array 2.
* If contains than add it to "foundNum" arraylist.
*/
if (a[i] == b[j]) {
foundNum.add(a[i]);
// Remove the number which exists in both arrays from "notFoundNum" arraylist.
if (notFoundNum.contains(a[i])) {
for (int k = 0; k < notFoundNum.size(); k++) {
if (notFoundNum.get(k) == a[i]) {
notFoundNum.remove(k);
}
}
}
break;
} // First if block ends
/**
* Checks if a not found number does not exists in 'notFoundNum' arraylist (to reduce redundancy)
* then adds a not found number to 'notFoundNum' arraylist
* */
if (!notFoundNum.contains(a[i]))
notFoundNum.add(a[i]);
} // Second for loop ends
} // First for loop ends
System.out.println("Found Numbers : " + foundNum);
System.out.println("Not Found Numbers : " + notFoundNum);
}
}
Here is the output for the above program:
Found Numbers : [1, 4, 8, 6, 6]
Not Found Numbers : [5, 65, 16, 575, 64, 561, 57]
Hi i am writing a lottery method where the user has to enter in two numbers, n and k, as arguments. The lottery gets filled with a randomized queue that goes up to k. so if i put in k=10 the queue would hold 1,2,3,4,5,6,7,8,9,10. The argument n is the number of items that has to be removed randomly. so if i chose 3 then it could return 4,6,8 or it could be 1,3,10.
Now if n is greater than k it has to throw an error saying that there is not enough items in the queue to pull. So if i put n=5 and k=3, there are still 3 items in the queue but i can't select 5 from the queue because that's too many.
Now my problem is i have to return the items that are still in the queue. so n=5 and k=3 would return 1,3,2 or 2,3,1 and so forth. But i have to print an exception after i return that array. So far i am able to return the array but i can not get the try catch exception to work. Is there another method i can try that will return the array and then print out the exception after that so it looks like this:
%java Lottery 5 2 //calls the method with the arguments n=5 k=2
2 1 //still prints the items in the queue
java.lang.Exception: Not enough items in your queue. // returns the error as well
at Lottery.pickNumbers(Lottery.java:29) //dont pay attention to these line numbers, this was a test case given to us
at Lottery.main(Lottery.java:56)
Here's my code:
import java.util.*;
import java.math.*;
public class Lottery{
RandomizedQueue rq;
Random Rnum = new Random();
int [] Larray;
// constructs a Lottery class
public Lottery(){
}
// picks the numbers and store them in an array of integers
// int n: number of items to pick
// int k: maximum integer to be picked
public int [] pickNumbers(int n, int k) throws Exception{
rq = new RandomizedQueue();
int [] remainQueue = new int [k];
if(n>k)
{
for(int i=1; i<=remainQueue.length;i++)
{
rq.enqueue(i);
}
for(int i=0; i<remainQueue.length;i++)
{
remainQueue[i] = rq.dequeue();
}
return remainQueue;
}
for(int i =1;i<=k;i++)
{
rq.enqueue(i);
}
Larray = new int[n];
for(int i = 0;i< Larray.length;i++)
{
Larray[i] = rq.dequeue();
}
return Larray;
}
// Do not change main().
public static void main(String [] args) throws Exception{
if (args.length<2){
System.out.println("Please enter your input values.");
System.out.println("e.g. java Lottery [number of integers to pick] [Maximum integer to be picked]");
}else{
int n = Integer.parseInt(args[0]);
int k = Integer.parseInt(args[1]);
Lottery l = new Lottery();
try{
int [] picked = l.pickNumbers(n,k);
for (int i = 0; i< picked.length; i++){
System.out.print(picked[i]+" ");
}
System.out.println();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
For this purpose you need to create your own custom Exception.
Follow the Steps.
-> Create an class that Extends Exception
-> write your own exceptions and handling
Say,
public class MyException extends Exception {
// special exception code goes here
}
Throw it as:
throw new MyException ("Something happened")
Catch as:
catch (MyException e)
{
// something
}
Here in your case
if(n
Change your main method like below code. In case of no exception you will get Result as expected in case of exception jut get previously populated Array and display that. In this way you will get populated result as well as exception both.
import java.util.*;
import java.math.*;
public class Lottery{
RandomizedQueue rq;
Random Rnum = new Random();
int [] Larray;
// constructs a Lottery class
public Lottery(){
}
// picks the numbers and store them in an array of integers
// int n: number of items to pick
// int k: maximum integer to be picked
public int [] pickNumbers(int n, int k) throws Exception{
rq = new RandomizedQueue();
int [] remainQueue = new int [k];
if(n>k)
{
for(int i=1; i<=remainQueue.length;i++)
{
rq.enqueue(i);
}
for(int i=0; i<remainQueue.length;i++)
{
remainQueue[i] = rq.dequeue();
}
return remainQueue;
}
for(int i =1;i<=k;i++)
{
rq.enqueue(i);
}
Larray = new int[n];
for(int i = 0;i< Larray.length;i++)
{
Larray[i] = rq.dequeue();
}
return Larray;
}
// Do not change main().
public static void main(String [] args) throws Exception{
if (args.length<2){
System.out.println("Please enter your input values.");
System.out.println("e.g. java Lottery [number of integers to pick] [Maximum integer to be picked]");
}else{
int n = Integer.parseInt(args[0]);
int k = Integer.parseInt(args[1]);
Lottery l = new Lottery();
try{
int [] picked = l.pickNumbers(n,k);
for (int i = 0; i< picked.length; i++){
System.out.print(picked[i]+" ");
}
System.out.println();
}catch (Exception e){
int [] picked = l.Larray;
for (int i = 0; i< picked.length; i++){
System.out.print(picked[i]+" ");
}
System.out.println();
e.printStackTrace();
}
}
}
}
You can't. Doing it doesn't even make sense. Exceptions are used for Exceptional behaviour. From what I understand asking for more items than is in the queue, is expected behaviour (ie. You have a use case which says "return the remaining queue". Thus if you want to handle the error, you should simply do something like.
if (picked.length != k)
{
System.out.println("You are attempting to choose more numbers than there are items (left) in the pool");
}
Alternatively since you know up front the values n and K you could simply do some input validation
if (k>n)
{
System.out.println("The amount of available numbers is smaller than the amount of numbers you wish to draw.")
}
Also you should probably use a Set instead of an Array.
This is how I would do it. Complete working code:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Lottery {
public void pickNumbers (int n, int k, List<Integer> values)
throws Exception
{
RandomizedQueue <Integer> rq = new RandomizedQueue <Integer> ();
for (int i = 0; i < k; i++)
rq.enqueue (i);
if (n <= k)
{
for (int i = 0; i < n; i++)
values.add (rq.dequeue ());
}
else
{
for (int i = 0; i < k; i++)
values.add (rq.dequeue ());
throw new Exception ("N > K");
}
}
public static void main (String [] args)
{
int n = Integer.parseInt (args [0]);
int k = Integer.parseInt (args [1]);
Lottery l = new Lottery ();
List <Integer> picked = new ArrayList <Integer> (n);
try
{
l.pickNumbers (n, k, picked);
}
catch (Exception e)
{
e.printStackTrace();
}
for (int i = 0; i < picked.size (); i++){
System.out.print (picked.get (i) + " ");
}
System.out.println();
}
private static class RandomizedQueue <T> extends ArrayList <T>
{
private final Random r = new Random ();
public void enqueue (T x)
{
add (x);
}
public T dequeue ()
{
return remove (r.nextInt(size ()));
}
}
}
Try this approach:
Create a list in main()
Pass that list to pickNumbers()
Make pickNumbers() return void and add the results to the list instead.
When you run into an error, throw the exception
In main(), catch the exception. The list will then contain all the results that have been computed so far.
Alternatively, write your own exception which accepts the existing results as arguments. main() can then read them from the exception.
You can either return value of throw Exception from a method, both can not be done at once.
You can create custom Exception class and where you can keep your processed result and throw that if exception arise.
public class MyException extends Exception{
private int[] processedResult;
public MyException(String str,int[] result){
this.processedResult = result;
}
...
#override
public String toString(){
....
}
}
...
public int [] pickNumbers(int n, int k) throws MyException{
int[] larray = new int[n];
try{
...
}catch(Exception ex){
new MyException("...",larray );
}
}
You can create your own Exception type which overrides setMessage
or simple instead of e.printStackTrace() use e.getMessage()
You can't both throw an exception and return a value at the same time.
Take a step back and look at what you are trying to achieve. You need to return multiple values from your method - a list of numbers and a status - which would suggest to me returning a complex object containing these values instead of a plain int[]:
public class LotteryPick {
public int status;
public int[] numbers;
}
public LotteryPick pickNumbers(int n, int k) {
...
}
In reality I'd use a Set<Integer> for numbers, an enum for status, and probably getter/setters for the fields.
Alternatively, if you must throw an exception, create a custom exception class (... extends IllegalArgumentException ?) that also has an int[] field to hold the picked numbers. I wouldn't recommend this approach though and it's functionally equivalent to the above in any case.