Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

//package com.java2s;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigInteger;

import java.util.ArrayList;
import java.util.Collection;

import java.util.HashSet;

import java.util.LinkedList;

import java.util.Map;
import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;

public class Main {
    private static final Map<Class<?>, Boolean> _customHash = new ConcurrentHashMap<Class<?>, Boolean>();
    private static final Map<Class<?>, Collection<Field>> _reflectedFields = new ConcurrentHashMap<Class<?>, Collection<Field>>();

    public static int deepHashCode(Object obj) {
        Set visited = new HashSet();
        LinkedList<Object> stack = new LinkedList<Object>();
        stack.addFirst(obj);
        int hash = 0;

        while (!stack.isEmpty()) {
            obj = stack.removeFirst();
            if (obj == null || visited.contains(obj)) {
                continue;
            }

            visited.add(obj);

            if (obj.getClass().isArray()) {
                int len = Array.getLength(obj);
                for (int i = 0; i < len; i++) {
                    stack.addFirst(Array.get(obj, i));
                }
                continue;
            }

            if (obj instanceof Collection) {
                stack.addAll(0, (Collection) obj);
                continue;
            }

            if (obj instanceof Map) {
                stack.addAll(0, ((Map) obj).keySet());
                stack.addAll(0, ((Map) obj).values());
                continue;
            }

            if (hasCustomHashCode(obj.getClass())) {
                hash += obj.hashCode();
                continue;
            }

            Collection<Field> fields = getDeepDeclaredFields(obj.getClass());
            for (Field field : fields) {
                try {
                    stack.addFirst(field.get(obj));
                } catch (Exception ignored) {
                }
            }
        }
        return hash;
    }

    private static int getLength(int from, int to) {
        int newLength = to - from;
        if (newLength < 0) {
            StringBuffer sb = new StringBuffer(from);
            sb.append(" > ").append(to);
            throw new IllegalArgumentException(sb.toString());
        }
        return newLength;
    }

    public static boolean hasCustomHashCode(Class<?> c) {
        Class<?> origClass = c;
        if (_customHash.containsKey(c)) {
            return _customHash.get(c);
        }
        while (!Object.class.equals(c)) {
            try {
                c.getDeclaredMethod("hashCode");
                _customHash.put(origClass, true);
                return true;
            } catch (Exception ignored) {
            }
            c = c.getSuperclass();
        }
        _customHash.put(origClass, false);
        return false;
    }

    public static int hashCode(byte[] data) {
        if (data == null) {
            return 0;
        }

        int i = data.length;
        int hc = i + 1;

        while (--i >= 0) {
            hc *= 257;
            hc ^= data[i];
        }

        return hc;
    }

    public static int hashCode(char[] data) {
        if (data == null) {
            return 0;
        }

        int i = data.length;
        int hc = i + 1;

        while (--i >= 0) {
            hc *= 257;
            hc ^= data[i];
        }

        return hc;
    }

    public static int hashCode(int[][] ints) {
        int hc = 0;

        for (int i = 0; i != ints.length; i++) {
            hc = hc * 257 + hashCode(ints[i]);
        }

        return hc;
    }

    public static int hashCode(int[] data) {
        if (data == null) {
            return 0;
        }

        int i = data.length;
        int hc = i + 1;

        while (--i >= 0) {
            hc *= 257;
            hc ^= data[i];
        }

        return hc;
    }

    public static int hashCode(short[][][] shorts) {
        int hc = 0;

        for (int i = 0; i != shorts.length; i++) {
            hc = hc * 257 + hashCode(shorts[i]);
        }

        return hc;
    }

    public static int hashCode(short[][] shorts) {
        int hc = 0;

        for (int i = 0; i != shorts.length; i++) {
            hc = hc * 257 + hashCode(shorts[i]);
        }

        return hc;
    }

    public static int hashCode(short[] data) {
        if (data == null) {
            return 0;
        }

        int i = data.length;
        int hc = i + 1;

        while (--i >= 0) {
            hc *= 257;
            hc ^= (data[i] & 0xff);
        }

        return hc;
    }

    public static int hashCode(BigInteger[] data) {
        if (data == null) {
            return 0;
        }

        int i = data.length;
        int hc = i + 1;

        while (--i >= 0) {
            hc *= 257;
            hc ^= data[i].hashCode();
        }

        return hc;
    }

    public static Collection<Field> getDeepDeclaredFields(Class<?> c) {
        if (_reflectedFields.containsKey(c)) {
            return _reflectedFields.get(c);
        }
        Collection<Field> fields = new ArrayList<Field>();
        Class<?> curr = c;

        while (curr != null) {
            try {
                Field[] local = curr.getDeclaredFields();

                for (Field field : local) {
                    if (!field.isAccessible()) {
                        try {
                            field.setAccessible(true);
                        } catch (Exception ignored) {
                        }
                    }

                    int modifiers = field.getModifiers();
                    if (!Modifier.isStatic(modifiers) && !field.getName().startsWith("this$")
                            && !Modifier.isTransient(modifiers)) {
                        fields.add(field);
                    }
                }
            } catch (ThreadDeath t) {
                throw t;
            } catch (Throwable ignored) {
            }

            curr = curr.getSuperclass();
        }
        _reflectedFields.put(c, fields);
        return fields;
    }
}