I was wondering if it was better to have a method for this and pass the Array to that method or to write it out every time I want to check if a number is in the array.
For example:
public static boolean inArray(int[] array, int check) {
for (int i = 0; i < array.length; i++) {
if (array[i] == check)
return true;
}
return false;
}
Thanks for the help in advance!
Since atleast Java 1.5.0 (Java 5) the code can be cleaned up a bit. Arrays and anything that implements Iterator (e.g. Collections) can be looped as such:
public static boolean inArray(int[] array, int check) {
for (int o : array){
if (o == check) {
return true;
}
}
return false;
}
In Java 8 you can also do something like:
// import java.util.stream.IntStream;
public static boolean inArray(int[] array, int check) {
return IntStream.of(array).anyMatch(val -> val == check);
}
Although converting to a stream for this is probably overkill.
You should definitely encapsulate this logic into a method.
There is no benefit to repeating identical code multiple times.
Also, if you place the logic in a method and it changes, you only need to modify your code in one place.
Whether or not you want to use a 3rd party library is an entirely different decision.
If you are using an array (and purely an array), the lookup of "contains" is O(N), because worst case, you must iterate the entire array. Now if the array is sorted you can use a binary search, which reduces the search time to log(N) with the overhead of the sort.
If this is something that is invoked repeatedly, place it in a function:
private boolean inArray(int[] array, int value)
{
for (int i = 0; i < array.length; i++)
{
if (array[i] == value)
{
return true;
}
}
return false;
}
You can import the lib org.apache.commons.lang.ArrayUtils
There is a static method where you can pass in an int array and a value to check for.
contains(int[] array, int valueToFind)
Checks if the value is in the given array.
ArrayUtils.contains(intArray, valueToFind);
ArrayUtils API
Using java 8 Stream API could simplify your job.
public static boolean inArray(int[] array, int check) {
return Stream.of(array).anyMatch(i -> i == check);
}
It's just you have the overhead of creating a new Stream from Array, but this gives exposure to use other Stream API. In your case you may not want to create new method for one-line operation, unless you wish to use this as utility.
Hope this helps!
Related
I am creating a function library for the class Frazione (it means fraction) and I need to work on the logical size of an array of type Frazione. How can I obtain it?
I tried a for loop and a while loop but I can't find the right way to separate the used indexes from the unused ones.
public static int size(Frazione[] set) {
int size = 0;
for (int i = 0; i < set.length; i++)
if (set[i] != null) //the only way I know not to count unused indexes
size++;
return size;
}
It should return the number of elements in the array but it doesn't even run
Your code works fine. Just as an alternate you could do the same using stream API. There is count() method that returns long type. So you could cast it to int:
public static int size(Frazione[] set) {
return (int)Arrays.stream(set)
.filter(Objects::nonNull)
.count();
}
this (obvious) code i've writen works well, but for testing purposes, i should make it work for a "one million" sized array in a reasonable time by saving CPU Cycles and saving as much memory as i can.
any suggestions please?
!!! the array is arranged in ascending order !!!
import java.util.Arrays;
class A {
static boolean exists(int[] ints, int k) {
for(int integer : ints){
if(integer == k){
return true;
}
}
return false;
}
Since your array is in ascending order, one thing you could do (i think) is to make a binary search instead of a linear search.
You could use a Set<Integer> that relies on hashing rather than an array where you iterate sequentially.
static boolean exists(Set<Integer> ints, int k) {
return ints.contains(k);
}
You could convert the array to a Set and pass it to the method as many times as required :
Set<Integer> set = Arrays.stream(ints).boxed().collect(Collectors.toSet());
boolean isExist = exists(set, 15);
...
isExist = exists(set, 5005);
...
isExist = exists(set, 355);
I am currently learning Java. Today I am making a little program where I input numbers and the program shall write if they are sorted or not.
I think I got the logic right, but I got a little error that I can't handle.
package inlamningsuppgift_arSorterad;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;
public class ifSorted {
public static void main(String[] arg) {
LinkedList a = new LinkedList();
Scanner sc = new Scanner(System.in);
System.out.println("Input your numbers, end with the letter \\n");
while (sc.hasNextDouble())
a.add(sc.nextDouble());
if (ifSorted(a))
System.out.println("List is sorted");
else
System.out.println("List is not sorted");
}
private static boolean ifSorted(LinkedList a) {
Collections.sort(a);
return a;
}
}
make this substitution! it work with Java8:
1- a.stream().sorted().collect(Collectors.toList() create a new sorted list
2- .equal(a) the new list comes compares the current
private static boolean ifSorted(LinkedList a) {
return a.stream().sorted().collect(Collectors.toList()).equals(a);
}
Lets take a look at your aerSorterat method.
private static boolean aerSorterat(LinkedList a) {
Collections.sort(a);
return a;
}
private static boolean means that your method will return a boolean which is either true or false .You inserted list [a] then returned [a] .No boolean .With your code You don't need that method.However you must cut the if else statement out of the loop so that after the user inserts a String for ex: out. It checks your list out side the loop.You can use the method if you want by inserting your if else statement in it and returning true or false then calling that method in the main method using ifsorted.aerSorterat(a);
You are actually trying to sort your list there with Collections.sort(a), but if you want to see if your values are sorted, you can do it e.g. with a loop like this:
private static boolean isSorted(List<Double> list) {
return ascending(list) || descending(list);
}
If you have to check both ways, you easy do that with both methods connecting with an ||, which is an logical or.
The single methods simply check if all values in a list are greater (ascending) oder lesser (descending) then their predecessors.
private static boolean ascending(List<Double> list) {
for (int i = 1; i < list.size(); i++)
if (list.get(i - 1) > list.get(i))
return false;
return true;
}
private static boolean descending(List<Double> list) {
for (int i = 1; i < list.size(); i++)
if (list.get(i - 1) < list.get(i))
return false;
return true;
}
If one of the values doesn't fit the premise, it simply returns false. If the loop is completed and left normally, that means that all values are sorted.
But to do that, you have to give the generic parameter <Double> as a parameter to your method, otherwise you cannot compare the values with < and >. Also I use List instead of LinkedList because with that given, you can use any kind of List you want.
If you want to use other objects than numbers, you need to change it a little.
First possability is, the objects you want to use have to implement the Comparable Interface, which provides the compareTo(...) method. Which that given, you can is it e.g. like the following:
public boolean ascending(List<YourObject> list) {
for (int i = 1; i < list.size(); i++)
if (list.get(i-1).compareTo(list.get(i)) > 0)
return false;
return true;
}
Simply swap the operator for descending. This e.g. can be used with a list of Strings.
I am working on a school assignment. The objective is to practice GUI's, clone() methods, and using/ modifying existing code. I am trying to write an equals method in the way the instructor desires-- by using a clone of the object, removing items from the bag (returns boolean based on success or failure to remove).
The bag is represented in an array, and should return true in cases such as {1,2,3} and {3,2,1}, ie order does not matter, only the number of each number present in the arrays.
Here is the issue
It works in most cases, however there is a bug in cases where the bags contain numbers as such: {1,1,2} and {1,2,2} and other similar iterations. It is returning true instead of false.
I believe it has something to do with the remove() method we are supposed to use. If i understand it correctly, it is supposed to put the value at the 'end' of the array and decrease the manyItems counter (this is a variable for number of items in the array, because array.length is by default in the constructor 10.)
The code is largely written by another person. We had to import the existing files and write new methods to complete the task we were given. I have all the GUI part done so i will not include that class, only the used methods in the IntArrayBag class.
A second pair of eyes would be helpful. Thanks.
public class IntArrayBag implements Cloneable
{
// Invariant of the IntArrayBag class:
// 1. The number of elements in the bag is in the instance variable
// manyItems, which is no more than data.length.
// 2. For an empty bag, we do not care what is stored in any of data;
// for a non-empty bag, the elements in the bag are stored in data[0]
// through data[manyItems-1], and we don�t care what�s in the
// rest of data.
private int[ ] data;
private int manyItems;
public IntArrayBag( )
{
final int INITIAL_CAPACITY = 10;
manyItems = 0;
data = new int[INITIAL_CAPACITY];
}
public IntArrayBag clone( )
{ // Clone an IntArrayBag object.
IntArrayBag answer;
try
{
answer = (IntArrayBag) super.clone( );
}
catch (CloneNotSupportedException e)
{ // This exception should not occur. But if it does, it would probably
// indicate a programming error that made super.clone unavailable.
// The most common error would be forgetting the "Implements Cloneable"
// clause at the start of this class.
throw new RuntimeException
("This class does not implement Cloneable");
}
answer.data = data.clone( );
return answer;
}
public int size( )
{
return manyItems;
}
public boolean remove(int target)
{
int index; // The location of target in the data array.
// First, set index to the location of target in the data array,
// which could be as small as 0 or as large as manyItems-1; If target
// is not in the array, then index will be set equal to manyItems;
for (index = 0; (index < manyItems) && (target != data[index]); index++)
// No work is needed in the body of this for-loop.
;
if (index == manyItems)
// The target was not found, so nothing is removed.
return false;
else
{ // The target was found at data[index].
// So reduce manyItems by 1 and copy the last element onto data[index].
manyItems--;
data[index] = data[manyItems];
return true;
}
}
//I added extra variables that are not needed to try to increase readability,
//as well as when i was trying to debug the code originally
public boolean equals(Object obj){
if (obj instanceof IntArrayBag){
IntArrayBag canidate = (IntArrayBag) obj; // i know this can be changed, this was required
IntArrayBag canidateTest = (IntArrayBag) canidate.clone(); //this was created
//as a clone because it was otherwise referring to the same memory address
//this caused items to be removed from bags when testing for equality
IntArrayBag test = (IntArrayBag) this.clone();
//fast check to see if the two objects have the same number of items,
//if they dont will return false and skip the item by item checking
if (test.size() != canidateTest.size())
return false;
//the loop will go through every element in the test bag it will
//then remove the value that is present at the first index of the test bag
for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
int check = test.data[i];
//remove() returns a boolean so if the value is not present in each bag
//then the conditional will be met and the method will return false
boolean test1 = test.remove(check);
boolean test2 = canidateTest.remove(check);
if (test1 != test2)
return false;
}//end for loop
// if the loop goes through every element
//and finds every value was true it will return true
return true;
}//end if
else
return false;
}//end equals
}
I cannot see the big picture, as I havent coded GUIs in Java before, however, as far as comparing 2 int[] arrays, I would sort the arrays before the comparison. This will allow you to eliminate problem cases like the one you stated ( if sorting is possible), then apply something like:
while(array_1[index]==array_2[index] && index<array_1.length)
{index++;}
and find where did the loop break by checking the final value of index
Is it explicitly stated to use clone? You can achieve it easily by overriding the hashCode() for this Object.
You can override the hashCode() for this object as follows:
#Override
public int hashCode() {
final int prime = 5;
int result = 1;
/* Sort Array */
Arrays.sort(this.data);
/* Calculate Hash */
for(int d : this.data) {
result = prime * result + d;
}
/* Return Result */
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || this.getClass() != obj.getClass()){
return false;
}
return false;
}
If you want to continue using your implementation for equals to compare test and CandidateTest then also you can compute unique hashes and make decision based on the results.
Here is the code snippet:
/* Assuming that you have put size comparison logic on top
and the two objects are of same size */
final int prime = 31;
int testResult = 1;
int candidateTestResult = 1;
for(int i = 0; i < test.size(); i++) {
testResult = prime * testResult + test.data[i];
candidateTestResult = prime * candidateTestResult + candidateTest.data[i];
}
/* Return Result */
return testResult == candidateTestResult;
I believe the problem is in this line:
for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
The problem here is that test and canidateTest are the clones that you made, and you are removing elements from those bags. And any time you remove an element from the bag, the size will decrease (because you decrease manyItems, and size() returns manyItems). This means you're only going to go through half the array. Suppose the original size is 4. Then, the first time through the loop, i==0 and test.size()==4; the second time, i==0 and test.size()==3; the third time, i==2 and test.size()==2, and you exit the loop. So you don't look at all 4 elements--you only look at 2.
You'll need to decide: do you want to go through the elements of the original array, or the elements of the clone? If you go through the elements of the clone, you actually never need to increment i. You can always look at test.data[0], since once you look at it, you remove it, so you know test.data[0] will be replaced with something else. In fact, you don't need i at all. Just loop until the bag size is 0, or until you determine that the bags aren't equal. On the other hand, if you go through the elements of this.data (i.e. look at this.data[i] or just data[i]), then make sure i goes all the way up to this.size().
(One more small point: the correct spelling is "candidate".)
Maybe you should try SET interface
view this in detail :http://www.tutorialspoint.com/java/java_set_interface.htm
A set object cannot contains duplicate elements, so it's suitable for your assignment than build your own class.
For example:[1,1,2] and [1,2,2]
you can use this to test whether they are equal
arr1 = {1,1,2}
arr2 = {1,2,2}
Set<Integer> set = new HashSet<Integer>();
for(int i : arr1){//build set of arr1
if(set.contains(i)==false){
set.add(i)
}
}
for(int i:arr2){
if(set.contains(i)==false){
System.out.println('not equal');
break;
}
}
Hope this is helpful.
I'm pretty new to java and I'm trying to learn so I'm just wondering how I could preform a linear search through my array.
This is what I've done so far but it doesn't work.
public boolean contains(Object elem)
{
boolean result = false;
for(int i=0;i<this.vector.length;i++)
if(elem.equals(this.vector[i]))
result=true;
else
result=false;
return result;
}
public int indexOf(V elem)
{
int pos = 0;
for(int i=0;i<this.vector.length;i++)
if(this.vector[i].equals(elem))
pos=i;
else
pos= -1;
return pos;
}
Your contains() function only returns true if the passed elem is the last item in the array. If you find it, you should return true immediately.
Your indexOf() method suffers from the same issue.
You're missing a break after you've found the element.
Oneliner:
Arrays.asList(vector).indexOf(elem);
It just creates and deletes one more object (ArrayList) in the memory. Should not be a problem in the most of situations.
You need to break your loop when you find your match.
There are a few problems with that code: in both methods, you always search through the entire array, even if you have found the element already. In both methods, this is the source of a bug (and less importantly: it is not as efficient as it could be).
for(int i=0;i<this.vector.length;i++)
if(elem.equals(this.vector[i]))
return true;
return false;
(and similar for the other method) might be a better implementation.