Categories
discuss

How to copy HashMap (not shallow copy) in Java

I need to make a copy of HashMap<Integer, List<MySpecialClass> > but when I change something in the copy I want the original to stay the same. i.e when I remove something from the List<MySpecialClass> from the copy it stays in the List<MySpecialClass> in the original.

If I understand it correctly, these two methods create just shallow copy which is not what I want:

mapCopy = new HashMap<>(originalMap);
mapCopy = (HashMap) originalMap.clone();

Am I right?

Is there a better way to do it than just iterate through all the keys and all the list items and copy it manually?

Answer

You’re right that a shallow copy won’t meet your requirements. It will have copies of the Lists from your original map, but those Lists will refer to the same List objects, so that a modification to a List from one HashMap will appear in the corresponding List from the other HashMap.

There is no deep copying supplied for a HashMap in Java, so you will still have to loop through all of the entries and put them in the new HashMap. But you should also make a copy of the List each time also. Something like this:

public static HashMap<Integer, List<MySpecialClass>> copy(
    HashMap<Integer, List<MySpecialClass>> original)
{
    HashMap<Integer, List<MySpecialClass>> copy = new HashMap<Integer, List<MySpecialClass>>();
    for (Map.Entry<Integer, List<MySpecialClass>> entry : original.entrySet())
    {
        copy.put(entry.getKey(),
           // Or whatever List implementation you'd like here.
           new ArrayList<MySpecialClass>(entry.getValue()));
    }
    return copy;
}

If you want to modify your individual MySpecialClass objects, and have the changes not be reflected in the Lists of your copied HashMap, then you will need to make new copies of them too.

Categories
discuss

Exposing hidden APIs android L (SDK 21) in Android Studio

I have successfully extracted the class files from an android emulator and replaced them into my android.jar file residing inside my platformsandroid-21android.jar and I still cannot access the hidden methods. I have previously used android 19, but to keep my builds up to date. I know I can use reflection, but its so much easier having it natively supported inside Android Studio.

Using JD-GUI I can confirm that the classes and methods are inside the android.jar file yet Android Studio “cannot resolve symbol” on every one of them. I am confused majorly here. Thanks everyone.

EDIT: I do have repo setup so if compiling the android.jar file from source is possible, I would not mind doing that.

Answer

File > Invalidate Caches and Restart > Invalidate and Restart

I knew something was weird. I knew the methods were there in the jar, I knew it was something with Studio. Here it caches the methods 🙂

Doing what I posted in the first line fixes it! So happy! Hope others benefit!

Categories
discuss

Ant javac task errs out: [javac] warning: [options] bootstrap class path not set in conjunction with -source 1.6

I’m trying to run an ant task that uses axis2-ant-plugin-1.6.0.jarorgapacheaxis2toolantAntCodegenTask to perform a WSDL2Java operation.

At the top of the ant script, I define java6.boot.classpath:

    <property name="java6.boot.classpath" value="${env.JAVA6_BOOT_CLASSES}"/>

And I have the JAVA6_BOOT_CLASSES environment variable set to C:devjava64-bitjdk-1.6.0_45bin.

The pertinent ant target is as follows:

<!-- dist.jar target -->
<target name="dist.jar" depends="generate"
    description="Creates the web services client jar file">
    <echo>Compiling web services client code</echo>

    <javac srcdir="${project.javapath}" destdir="${build}" 
           source="1.6" target="1.6" 
           debug="true" debuglevel="lines,vars,source" 
           excludes="com/company/junit/**"
           bootclasspath="${java6.boot.classpath}"
           includeantruntime="false">

        <classpath refid="compile.classpath" />
    </javac>

    <echo>Creating ${jarname}.jar</echo>
    <jar destfile="${dist}/${jarname}.jar" basedir="${build}" />
    <echo>${jarname}.jar created</echo>
</target>

Trying to run that, however, I receive the titular error:

 [javac] warning: [options] bootstrap class path not set in conjunction with -source 1.6  

Any ideas? I feel like I’ve appropriately set the boot classpath for Java 1.6, but ant doesn’t seem to agree.

Answer

This is not Ant but the JDK’s javac emitting the warning.

If you use Java 7’s javac and -source for anything smaller than 7 javac warns you you should also set the bootstrap classpath to point to an older rt.jar – because this is the only way to ensure the result is usable on an older VM.

https://blogs.oracle.com/darcy/entry/bootclasspath_older_source

This is only a warning, so you could ignore it and even suppress it with

<compilerarg value="-Xlint:-options"/>

Alternatively you really install an older JVM and adapt your bootclasspath accordingly (you need to include rt.jar, not the bin folder)

Categories
discuss

Weird : UNEXPECTED TOP-LEVEL EXCEPTION: Execution failed for task app:dexDebug

I didn’t implement new libs but this problem occured while coding :

Error:Execution failed for task ‘:app:dexDebug’.

com.android.ide.common.internal.LoggedErrorException: Failed to run command: C:android-sdkbuild-tools21.1.1dx.bat –dex –no-optimize –output F:Android_DonbasReDonbasIDEANewappbuildintermediatesdexdebug –input-list=F:Android_DonbasReDonbasIDEANewappbuildintermediatestmpdexdebuginputList.txt Error Code: 2 Output: UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:502) at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:277) at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:491) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:168) at com.android.dx.merge.DexMerger.merge(DexMerger.java:189) at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:454) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:302) at com.android.dx.command.dexer.Main.run(Main.java:245) at com.android.dx.command.dexer.Main.main(Main.java:214) at com.android.dx.command.Main.main(Main.java:106)

my build.gradle :

 dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:21.0.3'
    compile 'com.google.android.gms:play-services:6.5.87'
    compile 'com.google.code.gson:gson:2.3'
    compile 'com.google.code.gson:gson:2.3'
    compile 'com.google.code.gson:gson:2.2.2'
    compile 'com.google.guava:guava:18.0'
    compile 'com.android.support:appcompat-v7:20.0.0'
    compile files('libs/android-async-http-1.4.6.jar')
    compile files('libs/AndroidSwipeLayout-v1.1.6.jar')
    compile files('libs/apache-mime4j-0.5.jar')
    compile files('libs/crashlytics.jar')
    compile files('libs/httpclient-4.2.1.jar')
    compile files('libs/httpcore-4.2.1.jar')
    compile files('libs/httpmime-4.2.1.jar')
    compile files('libs/nineoldandroids-2.4.0.jar')
    compile files('libs/ormlite-android-4.48.jar')
    compile files('libs/ormlite-core-4.48.jar')
    compile files('libs/ormlite-jdbc-4.48.jar')
    compile files('libs/osmdroid-android-4.2.jar')
    compile files('libs/slf4j-android-1.6.1-RC1.jar')
    compile files('libs/universal-image-loader-1.9.3.jar')
}



packagingOptions {
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.t'
    }

Answer

You may have hit the 65k methods limit. To use Google Play Services with more granularity, follow this guide, you can use only the parts that you want. This will possibly fix your problem.

Categories
discuss

Class not included in the aar

I’m using Android Studio 1.0.1.

I managed to configure Android Library module in a project, so it’s built into AAR.

My problem is that the AAR archive does not have my class inside. When I check MyProject/MyModule/build/intermediates/classes/debug/my/package/mymodule I can see my class compiled: MyClass.class

But when I enter to AAR (or unpack it), the very same directory (I mean the my/package/mymodule in classes.jar inside of the AAR file) contains only one file: BuildConfig.class

Why isn’t my class included in the AAR?

Answer

maybe it has to do with the proguard configuration i had the same problem, i resolved it by adding a rule in the proguard-rules file. here is exactly what i did:

  • adding rule -keep public class my.package.** { public *;} proguard-rules.pro file
  • run gradlew assemble on terminal

after that you will find your aar file in youModule/build/outputs/aar/ directory

Hope this help

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..