.contains() method not working -- finding an int in array Java - java

I have been looking for hours, all over the internet and SO, but cannot find anything that I understand! ( Very new at Java )
Upon compiling, it cannot find symbol of the contain method.
Here is the code:
public class LotteryTicket {
private String nameOfBuyer;
private int[] numberList;
private boolean search(int val) {
if (val >= 1 && val <= 50) {
if (numberList.contains(val)) {
return true;
} else {
return false;
}
}
}
I am very new at learning, and I do not know why this is happening.

int[] is a primitive array and does not have a method .contains(). If you used List<Integer> instead, that would give you a .contains() method to call.
Also, your search method must return a value even when val < 1 or val > 50.
If you need numberList to be an int[], you could try this:
private boolean search(int val) {
if (numberList != null && val >= 1 && val <= 50) {
for(int number : numberList) {
if (number == val) {
return true;
}
}
}
return false;
}
Or, you could do this:
private boolean search(int val) {
if (numberList != null && val >= 1 && val <= 50) {
return Arrays.asList(numberList).contains(val);
}
return false;
}

The List interface defines the method contains. Think of an interface as a contract that classes can "sign" (in Java this is done with the keyword implements) which says that the class must have certain things in its implementation. A very common implementation of the List interface is ArrayList, but Lists do not work very well with the primitive int type, so what you want to do is make an ArrayList of Integers.
The simplest way to make an ArrayList of Integers is to make an array of Integers first (I know, Java has a lot of weird steps required to get things working).
In addition, you want to make sure that boolean methods always return a boolean value or you will get a compiler error.
Here's a working example:
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
public class LotteryTicket {
private String nameOfBuyer;
private List<Integer> numberList;
private boolean search(int val) {
return (val >= 1 && val <=50) && numberList.contains(val);
}
public static void main(String[] args) {
LotteryTicket lt = new LotteryTicket();
Integer[] numberList = new Integer[] {2, 3, 4, 5, 42, 6};
lt.numberList = new ArrayList<Integer>(Arrays.asList(numberList));
System.out.println(lt.search(42)); // prints "true\n"
System.out.println(lt.search(25)); // prints "false\n"
}
}

Related

why won't my program accept int[] parameter in method when called in main?

for some reason when I try and add an integer array as the parameter of this method when I call it in my main method, it doesn't recognise the parameter as an array or something, I'm not sure why it does this. I call the array like this: has23([2,4]).
public static boolean has23(int[] n) {
Boolean correct = null;
while ((n.length == 2)) {
for (int i : n) {
Arrays.asList(n);
if (Arrays.asList(n).contains(2) || Arrays.asList(n).contains(3)) {
correct = true;
}
else;
correct = false;
}
}
System.out.println(correct);
return correct;
}
Because
has23([2, 4])
is not legal Java syntax. You can do
has23(new int[] { 2, 4 })
instead. Or
int[] arr = { 2, 4 };
has23(arr);
but not
has23({2, 4});

Sort String[] array based on number present in the String

I have an array that looks like:
array[] = {1c, 13d, 11d, 10d, 1h, 13h, 5s, 2s, 12d}
I want to sort the array based on the number present in the array So the end result would be:
{1c, 1h, 2s, 5s, 10d, 11d, 12d, 13d, 13h}
Is there a way to do it?
The best way to do this is by implementing the Comparator interface. When you decide how you plan to compare the strings, you can use the utility methods in Arrays class. Here is a complete working example.
import java.util.Arrays;
import java.util.Comparator;
public class Foo {
public static void main(String[] args) {
String[] myArray = {"1c", "13d", "11d", "10d", "1h", "13h", "5s", "2s", "12d"};
System.out.println(Arrays.toString(myArray));
Arrays.sort(myArray, new Comparator<String>() {
#Override
public int compare(String one, String two) {
int oneNum = Integer.parseInt(one.substring(0, one.length() - 1));
int twoNum = Integer.parseInt(two.substring(0, two.length() - 1));
char oneChar = one.charAt(one.length() - 1);
char twoChar = two.charAt(two.length() - 1);
if (oneNum < twoNum) {
return -1;
} else if (oneNum == twoNum) {
if (oneChar < twoChar) {
return -1;
} else if (oneChar == twoChar){
return 0;
} else {
return 1;
}
} else {
return 1;
}
}
}
);
System.out.println(Arrays.toString(myArray));
}
}
Think about how you'd do this with just paper and pencil (no computer). Chances are you would:
Go through each element of the array, and convert it to just an integer (i.e. remove the non-numerical characters)
Sort the resulting integer-only array or list. Hint: Collections.sort() is your friend :)

Filtering and transforming a collection using Google Guava

Imagine the following object
class Trip {
String name;
int numOfTravellers;
DateMidnight from;
DateMidnight too;
}
I have written a manual recursive filter and transform method in java. However, I think this could be written more eloquently using Google Guava.
Can someone help me out and tell me how I can rewrite this to make more readable?
Basically what this method does, is locating equal entries, and combining the ones that are equal by altering the date fields
List<Trip> combineEqual(List<Trip> list) {
int n = list.size() - 1;
for (int i = n; i >= 0; i--) {
for (int j = n; j >= 0; j--) {
if (i == j) {
continue;
}
if (shouldCombineEqual(list.get(i), list.get(j))) {
Trip combined = combine(list.get(i), list.get(j));
list.remove(i);
list.remove(j);
list.add(Math.min(i, j), combined);
return combineEqual(liste);
}
}
}
return list;
}
private boolean shouldCombineEqual(Trip a, Trip b) {
return shouldCombineWith(a, b) || shouldCombineWith(b, a);
}
private boolean shouldCombineWith(Trip a, Trip b) {
return a.too() != null
&& a.too().plusDays(1).equals(b.from)
&& areEqual(a, b);
}
private boolean areEqual(Trip a, Trip b) {
return equal(a.name,b.name) && equal(a.numOfTravellers, b.numOfTravellers);
}
private boolean equal(Object a, Object b) {
return a == null && b == null || a != null && a.equals(b);
}
private Trip combineEqual(Trip a, Trip b) {
Trip copy = copy(a); //Just a copy method
if (a.from.isAfter(b.from)) {
Trip tmp = a;
a = b;
b = tmp;
} // a is now the one with the earliest too date
copy.from = a.from;
copy.too = b.too;
return copy;
}
I don't think Guava can help much here. There's a lot you can improve without it:
Create a TripKey {String name; int numOfTravellers;}, define equals, and use it instead of your misnamed areEqual. Split your trips into lists by their keys - here ListMultimap<TripKey, Trip> can help.
For each key, sort the corresponding list according to from. Try to combine each trip with all following trips. If it gets combined, restart the inner loop only. This should be already much clearer (and faster) than your solution... so I stop here.
I'd just use a HashSet.
First define equals and hashcode in your trip object. Add the first list to the set. Then iterate through the second list checking if a matching trip is already in the set. Something like:
public static Set<Trip> combineEquals(List<Trip> 11, List<Trip> 12) {
Set<Trip> trips = new HashSet<>(11);
for ( Trip t: 12) {
if ( trips.contains(t)) {
// combine whats in the set with t
} else {
trips.add(t);
}
}
return trips;

The functional way to do "max" (with recursion / without mutable vars)

Finding a max in an unsorted array with imperative code is quite straight forward
e.g. in Java (I'm sure it can be written better, only used for illustration purposes)
public class Main {
public static void main(String[] args) {
int[] array = {1,3,5,4,2};
int max = findMax(array);
System.out.println(max);
}
public static int findMax(int[] array){
int max = Integer.MIN_VALUE; //or array[0], but it requires a null check and I want to keep it simple :)
for (int i = 0, size = array.length; i < size ; i++) {
int current = array[i];
if(current > max) max = current;
}
return max;
}
}
What is the functional way of doing it? e.g.
without mutable variables (e.g. make max be a val in Scala / final in Java)
without looping (e.g. use recursion, tail preferred)
In Scala's sources I saw it was done using recudeLeft, which seems quite clever
def max[B >: A](implicit cmp: Ordering[B]): A = {
if (isEmpty)
throw new UnsupportedOperationException("empty.max")
reduceLeft((x, y) => if (cmp.gteq(x, y)) x else y)
}
But let's say I don't have (for some reason) reduce / reduceLeft available / implemented (And I don't want / can't implement it for some reason, i.e. I'm working with plain Java)
What is the "idiomatic" functional way to do a max without relying on other functional methods (e.g. how would I implement it in bare bones Java for example, but with the functional paradigm in mind)
Answers can be with any language (Java / Scala preferred though)
This is a tail call recursion implementation with accumulator for the max value.
public class Main {
public static void main(String[] args) {
System.out.println(max(new int[]{6, 3, 9, 4}));
}
public static int max(int[] ints) {
return max(ints, Integer.MIN_VALUE);
}
public static int max(int[] ints, int max) {
if (ints.length == 0) {
return max;
} else {
return max(Arrays.copyOfRange(ints, 1, ints.length), ints[0] > max ? ints[0] : max);
}
}
}
You can do it with a plain recursion but maba's tail recursion version should have a better performance.
import java.util.Arrays;
public class TestMax {
public static int findMax(int[] array) {
if(array.length == 1)
return array[0];
int[] newArray = Arrays.copyOfRange(array, 1, array.length);
if(array[0] > findMax(newArray))
return array[0];
else
return findMax(newArray);
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = {1,3,5,4,2, 9};
int max = findMax(array);
System.out.println(max);
}
}
Based on maba's excellent answer here is the Scala version if anyone was interested
def max(list: List[Int]) = {
maxAcc(list, Int.MinValue)
}
def maxAcc(list: List[Int], curMax:Int):Int = {
list match {
case Nil => curMax
case head :: tail => maxAcc(tail, if (head > curMax ) head else curMax )
}
}
Edit: thanks to maba's comment on #tailrec - here is the modified version
def max(list: List[Int]) = {
#tailrec def maxAcc(list: List[Int], curMax: Int): Int = {
list match {
case Nil => curMax
case head :: tail => maxAcc(tail, if (head > curMax) head else curMax)
}
}
maxAcc(list, Int.MinValue)
}

Code for searching similar entires in multiple two-dimensional arrays

I´m trying to write the code for the problem described in my previous topic. The suggested solution was to use hashmaps to find similar entries in multiple arrays (arrays have the same number of columns, but they might have different number of rows).
Below is my sample code based on a code snippet of the user John B provided here. For simplicity and for debugging purpose, I created just 3 different one-dimensional rows instead of two-dimensional arrays. Also, for simplicity, the function equalRows should return true or false instead of row indexes.
So, in the below code the function equalRows should return false, because array3 has {1,3,4} and it does have {1,2,3}. Instead the function returns true. Why does it happen?
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
int[] array1 = {1,2,3};
int[] array2 = {1,2,3};
int[] array3 = {1,3,4};
boolean answ = equalRows(array1,array2,array3);
System.out.println(answ);
}
static class Row extends Object {
private int value;
private volatile int hashCode = 0;
public Row(int val) {
this.value = val;
}
#Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if((obj == null) || (obj.getClass() != this.getClass()))
return false;
// object must be Row at this point
Row row = (Row)obj;
return (value == row.value);
}
#Override
public int hashCode () {
final int multiplier = 7;
if (hashCode == 0) {
int code = 31;
code = multiplier * code + value;
hashCode = code;
}
return hashCode;
}
}
private static Map<Row, Integer> map(int[] array) {
Map<Row, Integer> arrayMap = new HashMap<Row, Integer>();
for (int i=0; i<array.length; i++)
arrayMap.put(new Row(array[i]), i);
return arrayMap;
}
private static boolean equalRows(int[] array1, int[] array2, int[] array3){
Map<Row, Integer> map1 = map(array1);
Map<Row, Integer> map2 = map(array2);
for (int i=0; i<array3.length; i++){
Row row = new Row(array3[i]);
Integer array1Row = map1.get(row);
Integer array2Row = map2.get(row);
if (array1Row != null || array2Row != null) {
return false;
}
}
return true;
}
}
Edit#1
Code is updated subject to suggested solution.
Edit#2
I checked out the suggested solution, but the function returns false even for: int[] array1 = {1,2,3}; int[] array2 = {1,2,3}; int[] array3 = {1,2,3}, although it should be true. I think the problem is with the function hashcode. So, any solution?
This line is wrong, it immediately returns true:
if (array1Row != null && array2Row != null) {
return true;
}
What you must do is this (completely invert the logic):
if (array1Row == null || array2Row == null) {
return false;
}
It is only getting as far as testing the first element in each array and returning true because they match.
You need to return false if any fail to match and then return true if there are no failures.
I'd also put a test of the lengths at the start of the equalRows method.

Categories