Is there any alternative way to identify instance of multidimensional object without hardcode on it?
//source
import java.util.LinkedList;
import java.util.List;
public class Test {
public static <T> boolean isPrimitiveWrapper(T p_obj) throws Exception {
if (Number.class.isInstance(p_obj) || Number[].class.isInstance(p_obj)) {
return true;
} else if (Boolean.class.isInstance(p_obj) || Boolean[].class.isInstance(p_obj)) {
return true;
} else if (Character.class.isInstance(p_obj) || Character[].class.isInstance(p_obj)) {
return true;
}
return false;
}
public static void main(String[] args) throws Exception {
Integer[][][] a = {{{0}}, {{1}}, {{0}}};
println(isPrimitiveWrapper(a));
println(isPrimitiveWrapper(a[0]));
println(isPrimitiveWrapper(a[0][0]));
println(isPrimitiveWrapper(a[0][0][0]));
}
public static <T> void println(T p_t) {
System.out.println(p_t);
}
}
//Actual Result
false
false
true
true
//Expected Result
true
true
true
true
Based on the example above, we have no problem to deal with non-array & single dimension array object, but it is fail to identify multidimensional array object.
It is too ugly to hardcode the number of dimension.
There's no standard way to determine, if the class itself is wrapper for primitive type or not, so, you can do something like this:
private static final Set <Class <?>> primitiveWrappers;
static {
Set <Class <?>> tmp = new HashSet<>();
tmp.add (Integer.class);
tmp.add (Boolean.class);
tmp.add (Character.class);
tmp.add (Long.class);
tmp.add (Double.class);
tmp.add (Float.class);
// ... have I forgotten smth?
primitiveWrappers = Collections.unmodifiableSet(tmp);
}
private static boolean isPrimitiveWrapperOrArrayOf(Object o) {
if (o.getClass().isArray())
return isPrimitiveWrapperOrArrayOf(o.getClass().getComponentType());
else
return primitiveWrappers.contains(o.getClass());
}
When you run isPrimitiveWrapperOrArrayOf, the class is being checked if it's array, if it is, we'll check it's component type (for example, that would be Integer[] for Integer[][]) in the same function isPrimitiveWrapperOrArrayOf, so this way we'll come to just SomeClass, which will be checked if it's contained inside hardcoded primitiveWrappers
By the way, you may take a look at Commons Lang, ClassUtils.wrapperToPrimitive may solve your problem.
Try this approach. I guess that's what you want.
But this code looks like some sort of a hack anyway
(which is not necessarily bad).
private static boolean isPrimitiveWrapper(Object obj){
if (obj == null) {
return false;
} else {
String cls = obj.getClass().getCanonicalName();
return "java.lang.Integer".equals(cls) ||
cls.startsWith("java.lang.Integer[]");
}
}
Here is another hack. Both codes should work OK though.
private static boolean isPrimitiveWrapper(Object obj){
if (obj == null) {
return false;
} else {
String cls = obj.getClass().getName();
cls = cls.replaceAll(";", "");
return cls.matches("\\[*L?java\\.lang\\.Integer");
}
}
public class Test {
public static <T> boolean isPrimitiveWrapper(T p_obj) throws Exception {
return isPrimitiveWrapper(p_obj.getClass());
}
public static boolean isPrimitiveWrapper(Class p_obj) throws Exception {
if (Number.class.isAssignableFrom(p_obj)) {
return true;
} else if (Boolean.class.isAssignableFrom(p_obj)) {
return true;
} else if (Character.class.isAssignableFrom(p_obj)) {
return true;
} else if (p_obj.isArray()) {
//To handle multi dimension array
while (p_obj.isArray()) {
p_obj = p_obj.getComponentType();
}
return isPrimitiveWrapper(p_obj);
}
return false;
}
public static boolean isPrimitiveWrapper(boolean p_obj) {
return false;
}
public static boolean isPrimitiveWrapper(byte p_obj) {
return false;
}
public static boolean isPrimitiveWrapper(short p_obj) {
return false;
}
public static boolean isPrimitiveWrapper(float p_obj) {
return false;
}
public static boolean isPrimitiveWrapper(int p_obj) {
return false;
}
public static boolean isPrimitiveWrapper(long p_obj) {
return false;
}
public static boolean isPrimitiveWrapper(char p_obj) {
return false;
}
public static boolean isPrimitiveWrapper(double p_obj) {
return false;
}
public static void main(String[] args) throws Exception {
Integer[][][] a = {{{0}}, {{1}}, {{0}}};
int[][][] b = {{{0}}, {{1}}, {{0}}};
println(isPrimitiveWrapper(a));
println(isPrimitiveWrapper(a[0]));
println(isPrimitiveWrapper(a[0][0]));
println(isPrimitiveWrapper(a[0][0][0]));
println(isPrimitiveWrapper(b));
println(isPrimitiveWrapper(b[0]));
println(isPrimitiveWrapper(b[0][0]));
println(isPrimitiveWrapper(b[0][0][0]));
}
public static <T> void println(T p_t) {
System.out.println(p_t);
}
}
Related
I want print single variable, array and maybe double array,
I use following code, add a type when I need it,
but ... as you see ... it works but not smart.
So, question is "Is there a smart way to print Arrays?"
import java.util.Arrays;
class Rec{
int val;
public String toString(){
return "" + val;
}
Rec(int val){this.val=val;}
}
public class Main
{
public static void main(String[] args) {
Rec r = new Rec(0);
Boolean[] ba = new Boolean[]{true, false, true, true};
Rec[] ra = new Rec[]{new Rec(1), new Rec(2), new Rec(3)};
int[][] iaa = new int[][]{{1,2,3}, {3,4,5}};
System.out.printf("r=%s ba=%s ra=%s iaa=%s \n", s(r), s(ba), s(ra), s(iaa));
}
static <T> String s(T n) {
if(n instanceof int[]){
return Arrays.toString((int[])n);
}else if(n instanceof int[][]){
return Arrays.deepToString((int[][])n);
}else if(n instanceof boolean[]){
return Arrays.toString((boolean[])n);
}else if(n instanceof boolean[][]){
return Arrays.deepToString((boolean[][])n);
}else if(n instanceof Boolean[]){
return Arrays.toString((Boolean[])n);
}else if(n instanceof Rec[]){
return Arrays.toString((Rec[])n);
//}else if(n instanceof T[]){ // error: illegal generic type for instanceof
// return Arrays.toString((T[])n);
}else{
return "" + n;
}
}
}
If you really want to customize your printing for variable arrays then why not do the following:
public static String s(Object s) {
return s.toString();
}
public static String s(Object[] s) {
return Arrays.toString(s);
}
public static String s(Object[][] s) {
return Arrays.deepToString(s);
}
// For each primitive type of your single or multi dimension
// declare the following for either single or multi dimensional
public static String s(int[][] s) {
return Arrays.deepToString(s);
}
public static String s(int[] s) {
return Arrays.toString(s);
}
But keep in mind you are basically repackaging what the API already does.
This is my whole code, the problem requires me to use Array for solution.
import java.lang.reflect.Array;
public class MyStack<T> {
public MyStack (Class<T[]> _class,int size){
final T[] values = (T[]) Array.newInstance(_class,size);
this.values = values;
this.size=size;
}
private T[] values;
private int top=0,size;
public void push(T nextElement){
if(isFull()){
System.out.println("full");
}
else {
values[top++] = nextElement;
}
}
public T pop(){
if(isEmpty()) {
System.out.println("empty");
return null;
}
else {
return values[top--];
}
}
public boolean isEmpty(){
if (top==0)return true;
return false;
}
public boolean isFull(){
if(top==size-1)return true;
else return false;
}
public static void main(String args[]){
MyStack<Integer> myStack = new MyStack<Integer>(Integer[].class,9);
for (int i =0;i<10;i++)
{
myStack.push(i);
}
while(!myStack.isEmpty()){
System.out.println(myStack.pop());
}
}
}
When i compile it it throws Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer at values[top++] = nextElement; no matter which type i used from String, Integer or any other Objects.
Is there a way to fix this problem ?
You constructor takes a Class<T[]> but should take a Class<T>, also you don't need a variable shadow on values. I'd write it like
public MyStack(Class<T> _class, int size) {
this.values = (T[]) Array.newInstance(_class, size);
this.size = size;
}
You don't need if else chains for isEmpty (just return the condition you are testing directly) - like
public boolean isEmpty() {
return top == 0;
}
Or for isFull
public boolean isFull() {
return top == size - 1;
}
I'm having difficulty passing arrays between methods, I've managed to set them all to false from boolean, and returned the array to the main. However from there I don't know how to pass it to another method, and then later display the boolean true array as "yes" or the boolean false array as "no". My code looks as follows:
import javax.swing.*;
class methodarrays
{
public static void main (String[]param)
{
arrays();
seen();
display();
}
public static boolean[] arrays()
{
boolean [] birds = new boolean [5];
for (int i=0;i<birds.length;i++)
{
birds[i]=false;
}
return birds;
}
public static boolean seen()
{
String quit = "100";
String ans = "";
while(!ans.eqauls(quit))
{
ans=JOptionPane.showInputDialog(null,"Which bird are you reporting? \n 1) Blue Tit 2) Blackbird 3)Robin 4)Wren 5)Greenfinch");
if (ans.equals("1"))
{
birds[0] = true;
return birds[0];
}
else if (ans.equals("2"))
{ birds[1] = true;
return birds[1];
}
else if (ans.equals("3"))
{
birds[2] = true;
return birds[2];
}
else if (ans.equals("3"))
{
birds[2] = true;
return birds[2];
}
else if (ans.equals("4"))
{
birds[3] = true;
return birds[3];
}
else if (ans.equals("5"))
{
birds[4] = true;
return birds[4];
}
}
}
public static void display()
{
JOptionPane.showMessageDialog(null,"Your Garden Watch results are:");
}
}
To give you are starting hand... you can set the result of your arrays method to a local variable in the main method and pass as a argument to the seen. Then you can do the same for the display method.
public static void main (String[]param)
{
boolean[] birds = arrays();
seen(birds);
display(birds);
}
public static boolean[] arrays()
{
...
}
public static boolean seen(boolean[] birds)
{
...
There are plenty of tutorials around the web for this kind thing. Here being one example.
You need to pass it as a parameter or declare a global array.
Passing by parameter:
class methodarrays {
public static void main (String[]param)
{
boolean [] myArray =arrays();
seen(myArray);
display(myArray);
}
public static boolean seen(boolean [] myArrayParam)
{
for (int i=0;i<myArrayParam.length;i++)
{...}
}
public static boolean display(boolean [] myArrayParam)
{
for (int i=0;i<myArrayParam.length;i++)
{...}
}
}
As global array:
class methodarrays {
boolean [] myArray
public static void main (String[]param)
{
myArray = arrays();
seen();
display();
}
public static boolean seen()
{
for (int i=0;i<myArray.length;i++)
{...}
}
public static boolean display()
{
for (int i=0;i<myArray.length;i++)
{...}
}
}
Declare
boolean [] birds = new boolean [5];
as accessible object for all methods within your class.
import javax.swing.*;
class methodarrays
{
private boolean [] birds = new boolean [5]
...
public static boolean[] arrays()
{
for (int i=0;i<birds.length;i++)
{birds[i]=false;
}
return birds;
}
...
}
Here is the implementation mimicing your own:
import javax.swing.JOptionPane;
public class Example {
private static boolean [] birds = new boolean [5];
public static void main (String[]param){
arrays();
seen();
display();
}
public static boolean[] arrays()
{
// Completely unnecessary since values are set to false by default;
for (int i=0;i<birds.length;i++)
{birds[i]=false;
}
return birds;
}
public static void seen(){
String quit = "100";
String ans = "";
while(!ans.equals(quit))
{
ans=JOptionPane.showInputDialog(null,"Which bird are you reporting? \n 1) Blue Tit 2) Blackbird 3)Robin 4)Wren 5)Greenfinch");
if (ans.equals("1"))
{ birds[0] = true;
}
else if (ans.equals("2"))
{ birds[1] = true;
}
else if (ans.equals("3"))
{ birds[2] = true;
}
else if (ans.equals("3"))
{ birds[2] = true;
}
else if (ans.equals("4"))
{ birds[3] = true;
}
else if (ans.equals("5"))
{ birds[4] = true;
}
}
}
public static void display(){
System.out.println("Your results are: ");
System.out.println("Blue Tit: " + birds[0]);
System.out.println("Blackbird: " + birds[1]);
//and so on..
}
}
Is there a single line implementation for the getInt method?
If not - can one implement it without using instanceof?
public class ParseInt {
public static void main(String[] args) {
Object intArr[] = { "131", 232, new Integer(333) };
for (Object intObj : intArr) {
System.out.println(getInt(intObj));
}
}
private static int getInt(Object obj) {
return // ???
}
}
Use Integer.valueOf(obj.toString)
private static int getInt(Object obj) {
return Integer.valueOf(obj.toString());
}
This will work for your object array
Try something like...
private static int getInt(Object obj) {
if (obj instanceof String) {
return Integer.parseInt((String) obj);
} else if(obj instanceof Integer){
return (Integer) obj;
} else{
return 0; // or else whatever you want
}
}
I'd like to write a method, that does return something of a PrimitiveType like float, integer, boolean and also String if possible. I'd like to use generics for it but i stuck and dont find a solution for it. I do need it for a Configparser. Ill use it to get different values from the Config.
Current it des look like this and i know that the switch does not work like this but you get an idea of what id like to do:
public class ConfigurationManager extends XmlReader {
private final static String FILE_PATH = "config/config.cfg";
private static Element xml;
public ConfigurationManager() throws IOException {
FileHandle handle = Gdx.files.internal(FILE_PATH);
this.xml = this.parse(handle);
}
public Resolution getResolution() {
Resolution r = new Resolution();
r.height = xml.getFloat("height");
r.width = xml.getFloat("width");
return r;
}
public static <T> T getConfig(Class<T> type, String name) {
if (type.equals(Integer.class)) {
return type.cast(xml.getInt(name));
} else if (type.equals(Float.class)) {
return type.cast(xml.getFloat(name));
} else if (type.equals(Boolean.class)) {
return type.cast(xml.getBoolean(name));
} else if (type.equals(String.class)) {
return type.cast(xml.get(name));
}
throw new AssertionError("Invalid type");
}
}
Thanks alot
Well, I don't think you can do it with primitive types directly, but how about something like this:
public static <T> T getConfig(Class<T> type, String name) {
if(type.equals(Integer.class)){
return type.cast(xml.getInteger(name));
} else if(type.equals(Float.class)){
return type.cast(xml.getFloat(name));
} else if(type.equals(Double.class)) {
return type.cast(xml.getDouble(name));
} else if(type.equals(String.class)) {
return type.cast(xml.getString(name));
}
throw new AssertionError("Invalid type");
}
You could use an Enum to avoid the branching logic and the explicit casting.
public enum TypeSelector {
INTEGER() {
#Override
public Integer getValue(Elements xml, String name) {
return xml.getInteger(name);
}
},
DOUBLE() {
#Override
public Double getValue(Elements xml, String name) {
return xml.getDouble(name);
}
};
private static final Map<Class<?>, TypeSelector> SELECTORS = new HashMap<Class<?>, TypeSelector>() {
{
put(Integer.class, INTEGER);
put(Double.class, DOUBLE);
}
};
public static <T> TypeSelector getSelectorForType(Class<T> c) {
TypeSelector selector = SELECTORS.get(c);
if (selector == null) {
throw new AssertionError("Invalid type");
}
return selector;
}
public abstract <T> T getValue(Elements xml, String name);
}