Is there any other class which and be use like java.util.stream.IntStream (of java 8) in java 6
I wanted to achieve
List<Integer> list = IntStream.of(intArray).boxed().collect(Collectors.toList());
how it is possible in java 6 or below
No, there's no simple way to do this in JDK6, that's exactly why they added it in JDK8.
You can either:
iterate over the int array and add the numbers one by one to the new collection
int[] intArray = { 1,2,3 };
List<Integer> ints = new ArrayList<>(intArray.length);
for (int i : intArray) {
ints.add(i);
}
or you can reach out for a library to do this for you. For example, Guava does this pretty well: Ints.asList()
If all you want is to convert an int[] into an List<Integer>
you can either:
create your own ArrayList and add the elements manually
List<Integer> list = new ArrayList<Integer>(intArray.length);
for(int value : intArray){
list.add(value);
}
Or you can easily write your own class that implements List using an primitive array backing:
public final class IntArrayList extends AbstractList<Integer> implements RandomAccess {
private final int[] array;
public IntArrayList(int[] array) {
this.array = array;
}
#Override
public Integer get(int index) {
return array[index];
}
#Override
public int size() {
return array.length;
}
#Override
public Integer set(int index, Integer element) {
Integer old = array[index];
array[index] = element.intValue();
return old;
}
public int indexOf(Object o) {
if(o==null){
return -1;
}
if(!(o instanceof Integer)){
return -1;
}
int val = ((Integer)o).intValue();
for (int i=0; i<array.length; i++){
if (val==array[i]){
return i;
}
}
return -1;
}
public boolean contains(Object o) {
return indexOf(o) != -1;
}
/**
* Optimization of equals since
* we know we are have an array of ints
* this should reduce boxing/unboxing
* on our end at least.
*/
#SuppressWarnings("rawtypes")
public boolean equals(Object o) {
if (o == this){
return true;
}
if (!(o instanceof List)){
return false;
}
int currentOffset=0;
ListIterator e2 = ((List) o).listIterator();
while(currentOffset<array.length && e2.hasNext()) {
Object o2 = e2.next();
//will return false if o2 is null
if(!(o2 instanceof Integer)){
return false;
}
if(array[currentOffset] !=((Integer)o2).intValue()){
return false;
}
currentOffset++;
}
return !(currentOffset<array.length || e2.hasNext());
}
/**
* Optimization of hashcode since
* we know we have an array of ints.
*/
public int hashCode() {
return Arrays.hashCode(array);
}
}
And then it's just
List<Integer> list = new IntArrayList(intArray);
Related
I'm writing a method that returns a Set<String>. The set may contain 0, 1, or 2 objects. The string keys are also quite small (maximum 8 characters). The set is then used in a tight loop with many iterations calling contains().
For 0 objects, I would return Collections.emptySet().
For 1 object, I would return Collections.singleton().
For 2 objects (the maximum possible number), a HashSet seems overkill. Isn't there a better structure? Maybe a TreeSet is slightly better? Unfortunately, I'm still using Java 7 :-( so can't use modern things like Set.of().
An array of 2 strings would probably give the best performance, but that's not a Set. I want the code to be self-documenting, so I really want to return a Set as that is the logical interface required.
Just wrap an array with an AbstractSet. You only have to implement 2 methods, assuming you want an unmodifiable set:
class SSet extends AbstractSet<String> {
private final String[] strings;
SSet(String[] strings) {
this.strings = strings;
}
#Override
public Iterator<String> iterator() {
return Arrays.asList(strings).iterator();
}
#Override
public int size() {
return strings.length;
}
}
If you want, you can store the Arrays.asList(strings) in the field instead of a String[]. You can also provide 0, 1 and 2-arg constructors if you want to constrain the array only to be that length.
You can also override contains:
public boolean contains(Object obj) {
for (int i = 0; i < strings.length; ++i) {
if (Objects.equals(obj, strings[i])) return true;
}
return false;
}
If you don't want to create a list simply to create an iterator, you can trivially implement one as an inner class:
class ArrayIterator implements Iterator<String> {
int index;
public String next() {
// Check if index is in bounds, throw if not.
return strings[index++];
}
public boolean hasNext() {
return index < strings.length;
}
// implement remove() too, throws UnsupportedException().
}
The set is then used in a tight loop with many iterations calling contains().
I would probably streamline it for this. Perhaps something like:
public static class TwoSet<T> extends AbstractSet<T> {
T a = null;
T b = null;
#Override
public boolean contains(Object o) {
return o.equals(a) || o.equals(b);
}
#Override
public boolean add(T t) {
if(contains(t)){
return false;
}
if ( a == null ) {
a = t;
} else if ( b == null ) {
b = t;
} else {
throw new RuntimeException("Cannot have more than two items in this set.");
}
return true;
}
#Override
public boolean remove(Object o) {
if(o.equals(a)) {
a = null;
return true;
}
if(o.equals(b)) {
b = null;
return true;
}
return false;
}
#Override
public int size() {
return (a == null ? 0 : 1) + (b == null ? 0 : 1);
}
#Override
public Iterator<T> iterator() {
List<T> list;
if (a == null && b == null) {
list = Collections.emptyList();
} else {
if (a == null) {
list = Arrays.asList(b);
} else if (b == null) {
list = Arrays.asList(a);
} else {
list = Arrays.asList(a, b);
}
}
return list.iterator();
}
}
You can achieve this by
Make a class that implements Set interface
Override add and remove method
Add value upon class initialisation by super.add(E element)
Use that class instead
I've implemented my program but I am getting an exception java.lang.ClassCastException
This is the code:
import java.util.NoSuchElementException;
public class BasePQStack<Item> implements Stack<Item> {
// TODO: implement this object.
private int N = 0;
private MaxPQ<Compare> pq = new MaxPQ<>();
private int count;
public BasePQStack() {
count = 0;
}
/**
* entry point for sample output..
*
* #param args
*/
public static void main(String[] args) {
Stack<Integer> S = new BasePQStack<Integer>();
S.push(new Integer(2));
S.push(new Integer(7));
Integer W = S.pop();
S.push(new Integer(8));
S.push(new Integer(5));
;
Integer X = S.pop();
Integer Y = S.peek();
S.push(new Integer(3));
Integer Z = S.pop();
System.out.println("Testing: ");
System.out.println(W);
System.out.println(X);
System.out.println(Y);
System.out.println(Z);
}
#Override
public Item push(Item item) {
Compare x = new Compare(item, count);
pq.insert(x);
count++;
N++;
return item;
}
#Override
public Item pop() {
if (isEmpty())
throw new NoSuchElementException("no such element");
else {
Item var = (Item) pq.delMax();
N--;
return var;
}
}
#Override
public Item peek() {
if (isEmpty())
throw new NoSuchElementException("no such element");
else {
Item var = (Item) pq.delMax();
push(var);
return var;
}
}
#Override
public boolean isEmpty() {
return N == 0;
}
#Override
public int size() {
return N;
}
public class Compare implements Comparable<Compare> {
private Item value;
private int a;
public Compare(Item value, int a) {
this.a = a;
this.value = value;
}
#Override
public int compareTo(Compare x) {
if (this.a > x.a)
return 1;
if (this.a < x.a)
return -1;
else
return 0;
}
public int getA() {
return this.a;
}
public Item getValue() {
return this.value;
}
#Override
public String toString() {
return "item {" + "value = " + value + ",a = " + a + '}';
}
}
}
The message I am getting from the console is BasePQStack$Compare cannot be cast to java.lang.Integer. I've tried to do many castings but could not figure anything out as it just led to more error
The output of the code should be:
7
5
8
3
You should probably replace this line
Item var = (Item) pq.delMax()
With
Item var = (Item) pq.delMax().getValue();
Because delMax() returns a compare object and you need a Item object.
From the Java documentation: Class cast exceptions are "thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance".
From the code you posted, it looks like it could be occurring when you attempt to cast something to an Item:
Item var = (Item) pq.delMax();
Probably because your queue does not contain objects of type Item, it contains objects of type Compare. In general be careful when you decide to downcast because the compiler errors are there to help you.
Your MaxPQ Key is of type Compare and when you push an Integer it gets wrapped in a Compare before being inserted into the MaxPQ.
The problem is when you pop or peek you do not do any unwrapping of the Compare to get back to the Integer. This is why you get a ClassCastException on any line that calls pop() or peek(). You are treating the Compare as if it is an Integer.
You need to modify your pop() and peek() methods as follows;
#Override
public Item pop() {
if (isEmpty()) {
throw new NoSuchElementException("no such element");
} else {
Item var = (Item) pq.delMax().getValue();
N--;
return var;
}
}
#Override
public Item peek() {
if (isEmpty()) {
throw new NoSuchElementException("no such element");
} else {
Item var = (Item) pq.delMax().getValue();
push(var);
return var;
}
}
Note the use of getValue(). This is what does the unwrapping I mentioned above i.e. it gets the Integer out of the Compare for you.
My Java assignment is to implement a set class by using an array.
The assignment won't allow me import the set class from the library, so I have to make it on my own. When I tried to print out the array, it prints out numbers in repeats, not unique numbers. I don't know where the problem is, so if you guys can find any errors in my code, it would be great. I tried to add numbers 2, 3, and 4 to the set, so the result should be 2 3 4, but the code shows me 2 3 2 3 2.
I think the source of the problem is from the add method from the set class, but I don't know what the problem is exactly.
import java.util.Arrays;
public final class Set implements SetInterface
{
private int[] set;
private int size;
private int capacity;
public Set(int c)
{
capacity = c;
set = new int[capacity];
size = 0;
}
public boolean contains(int x)
{
boolean contains = false;
for(int i = 0; i<capacity; i++)
{
if(x == set[i])
contains = true;
else
contains = false;
}
return contains;
}
public void add(int x)
{
for(int i = 0; i<capacity; i++)
{
if(!contains(x))
{
if(size == capacity)
{
set = Arrays.copyOf(set,size*2);
}
if(set[i]==0)
{
set[i++] = x;
}
}
}
size++;
}
public boolean remove(int x)
{
boolean remove = false;
for(int i = 0; i < capacity; i++)
{
if(x == set[i])
{
set[i] = set[size -1];
size--;
remove = true;
}
if(isEmpty())
{
remove = false;
}
}
return remove;
}
public void clear()
{
set = null;
size = 0;
}
public int size()
{
return size;
}
public boolean isEmpty()
{
if(size == 0)
return true;
else
return false;
}
public int[] toArray()
{
return Arrays.copyOf(set, capacity);
}
}
This is the driver class that I test my class.
import java.util.Arrays;
public class SetDriver
{
public static void main(String[] args)
{
SetDriver driver = new SetDriver();
Set s1 = new Set(5);
s1.add(2);
s1.add(3);
s1.add(4);
driver.print(s1);
System.out.println("Size: "+s1.size());
}
public static void print(Set s)
{
for(int i = 0; i<s.toArray().length; i++)
{
System.out.print(s.toArray()[i]+" ");
}
System.out.println("");
}
}
The outputs are here:
2 3 2 3 2
Size: 3
There's a likely problem with your contains method. Suppose that you did find a duplicate. What happens is that you assign your variable to true and you continue to iterate. This stomps over the logic entirely; you could have a duplicate but never act on it because your boolean code precludes you from doing so.
Ideally, when you find a match, you must stop iterating and return immediately.
public boolean contains(int value) {
for(int setItem : set) {
if(setItem == value) {
return true;
}
}
return false;
}
You should change add method like this.
public void add(int x) {
if (contains(x))
return;
if (size >= capacity) {
capacity *= 2;
set = Arrays.copyOf(set, capacity);
}
set[size++] = x;
}
I fill up an Array List with some numbers and want to find a specific number that is in the Array List and get its position (the index) in my Array List.
Any example would be great!
for example
ProClon.indexOf(spro.getId(id));
First override equals() method with the specified field. then You can use indexOf.(object)
class A {
int i;
// other fields
public A(int i) {
this.i = i;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
A a = (A) o;
return i == a.i;
}
#Override
public int hashCode() {
return i;
}
}
List<A> list = new ArrayList<>();
list.indexOf(new A(3));
check the api of arrayList. indexOf(Object o); does exactly what you need.
http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#indexOf(java.lang.Object)
Just use method indexOf in array
arrayName.indexOf(object)
It looks like the hashCode() and equals() for int[] are poorly implemented, or not implemented at all!
(Tested with Android, but I expect it to be true for any Java environment).
In order to get HashSet.contains() working properly, I had to create a wrapper for int[] (plse, don't criticize my coding style, look at the essence):
public class IntArray {
private int[] value;
public IntArray(int[] value) {
this.value = value;
}
#Override
public int hashCode() {
int sum = 0;
// Integer overflows are cheerfully welcome.
for (int elem: value) sum += elem;
return sum;
}
#Override
public boolean equals(Object o) {
if (o == null) return (value==null);
if (value != null) {
if (o instanceof int[])
return compare((int[])o);
if (o instanceof IntArray)
return compare(((IntArray)o).value);
}
return false;
}
protected boolean compare(int[] other) {
int len = value.length;
if (other.length != len) return false;
for (int i=0; i<len ; i++)
if (value[i] != other[i]) return false;
return true;
}
}
Works OK, but I prefer to avoid a custom wrapper or a third-party library. Is there an option?
Since the standard Java Hashtable does not allow an override of the hash code used for keys, you are out of luck and will need to use a wrapper like you did.
keep in mind that your hashCode implementation is very bad, you can use this (Taken from java.util.Arrays in the standard JDK) to get a better hash distrubtion:
public static int hashCode(int a[]) {
if (a == null)
return 0;
int result = 1;
for (int element : a)
result = 31 * result + element;
return result;
}
An alternative is to use a different Hashtable, which can deal with primitives.
one such option is Banana, which is a primitive collections library I created.
After Omry Yadan's message the hashCode function becomes as simple as that!
#Override
public int hashCode() {
return Arrays.hashCode(value);
}
For a RISC CPU, like ARM, It may be more efficient:
#Override
public int hashCode() {
int code = 0;
if (value != null) {
code++;
for (int elem: value)
code = (code<<5) - code + elem;
}
return code;
}
May be there is also a standard function for comparing arrays, in which case equals() can be simplified too?