简体   繁体   中英

ClassCastException from LinkedHashSet to String

I want to get array of Strings out of LinkedHashSet but I get ClassCastException in line where i try to print my values in foreach loop.

I get that there is something wrong with powerset method but when i tryed to fix it by adding LinkedHashSet inside method i failed.

I belive there is a way to get Strings out of object. Last thought was to write it in file and than parce with regex but it seems to exotic...

Trace: Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashSet cannot be cast to [Ljava.lang.String; at Main.main(Main.java:61)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.xml.stream.events.Characters;

public class Main {
     public static void main(String[] args) {

           String set[] = {"a", "b", "c", "d", "e"};
           char rset[] = new char[5];
           String sSet[] = null;
           String s1 = "";
           String s2 = "";
           ArrayList<char[]> arr = new ArrayList();
           arr.add(new char[]{'b','c','d'});
           arr.add(new char[]{'e','a', 'b'});
           arr.add(new char[]{'c','a'});
           arr.add(new char[]{'b','d','c'});
           arr.add(new char[]{'b','d','c'});

           int i=0;
           String buffer = "";
           for (char[] strings : arr) {
               System.out.println(Arrays.toString(strings));
               if(buffer.indexOf(strings[(strings.length)-1]) < 0){
                   buffer = buffer + strings[(strings.length)-1];
               }
               i++;
           }
           rset = buffer.toCharArray();
           Arrays.sort(rset);

           for (String ch : set) {
            s1+=ch + " ";
           }
           for (char ch : rset) {
                s2+=ch + " ";
            }

           System.out.println(s1);
           System.out.println(s2);
           String diff = difference(s1, s2);
           System.out.println(diff);

           //form the power set
           LinkedHashSet myPowerSet = powerset(set);
           //display the power set


           System.out.println(myPowerSet.toString());


           ArrayList<String[]> sArr = new ArrayList(myPowerSet);

           for (String[] strings : sArr) {
               System.out.println(strings);
           }
       }

    private static String difference(String s1, String s2) {
        String diff = "";
        String[] strList1 = s1.split(" ");
           String[] strList2 = s2.split(" ");

           List<String> list1 = Arrays.asList(strList1);
           List<String> list2 = Arrays.asList(strList2);

           // Prepare a union
           List<String> union = new ArrayList<>(list1);
           union.addAll(list2);

           // Prepare an intersection
           List<String> intersection = new ArrayList<>(list1);
           intersection.retainAll(list2);

           // Subtract the intersection from the union
           union.removeAll(intersection);

           for (String s : union) {
               //System.out.println(s);
               diff += s;
           }
           return diff;
    }

     private static LinkedHashSet powerset(String[] set) {

           //create the empty power set
           LinkedHashSet power = new LinkedHashSet();

           //get the number of elements in the set
           int elements = set.length;

           //the number of members of a power set is 2^n
           int powerElements = (int) Math.pow(2,elements);

           //run a binary counter for the number of power elements
           for (int i = 0; i < powerElements; i++) {

               //convert the binary number to a string containing n digits
               String binary = intToBinary(i, elements);

               //create a new set
               LinkedHashSet innerSet = new LinkedHashSet();

               //convert each digit in the current binary number to the corresponding element
                //in the given set
               for (int j = 0; j < binary.length(); j++) {
                   if (binary.charAt(j) == '1')
                       innerSet.add(set[j]);
               }

               //add the new set to the power set
               power.add(innerSet);

           }
           return power;
       }
       /**
         * Converts the given integer to a String representing a binary number
         * with the specified number of digits
         * For example when using 4 digits the binary 1 is 0001
         * @param binary int
         * @param digits int
         * @return String
         */
       private static String intToBinary(int binary, int digits) {

           String temp = Integer.toBinaryString(binary);
           int foundDigits = temp.length();
           String returner = temp;
           for (int i = foundDigits; i < digits; i++) {
               returner = "0" + returner;
           }
           return returner;
       } 
}

TL;DR

Use Generics


LinkedHashSet myPowerSet;

should actually be

LinkedHashSet<LinkedHashSet<String>> myPowerSet;

Make the necessary changings in your code and the answer will jump right in front of your eyes.

ArrayList<LinkedHashSet<String>> sArr = new ArrayList<>(myPowerSet);

Does not actually take String[] but String since its the type use in myPowerSet so the following would also be changed

for (Set strings : sArr) {
    System.out.println(strings);
}

Full Code

public static void main(String[] args) {

    String set[] = {"a", "b", "c", "d", "e"};
    char rset[] = new char[5];
    String sSet[] = null;
    String s1 = "";
    String s2 = "";
    ArrayList<char[]> arr = new ArrayList<char[]>();
    arr.add(new char[]{'b','c','d'});
    arr.add(new char[]{'e','a', 'b'});
    arr.add(new char[]{'c','a'});
    arr.add(new char[]{'b','d','c'});
    arr.add(new char[]{'b','d','c'});

    int i=0;
    String buffer = "";
    for (char[] strings : arr) {
        System.out.println(Arrays.toString(strings));
        if(buffer.indexOf(strings[(strings.length)-1]) < 0){
            buffer = buffer + strings[(strings.length)-1];
        }
        i++;
    }
    rset = buffer.toCharArray();
    Arrays.sort(rset);

    for (String ch : set) {
        s1+=ch + " ";
    }
    for (char ch : rset) {
        s2+=ch + " ";
    }

    System.out.println(s1);
    System.out.println(s2);
    String diff = difference(s1, s2);
    System.out.println(diff);

    //form the power set
    LinkedHashSet<LinkedHashSet<String>> myPowerSet = powerset(set);
    //display the power set


    System.out.println(myPowerSet.toString());


    ArrayList<LinkedHashSet<String>> sArr = new ArrayList<>(myPowerSet);

    for (Set strings : sArr) {
        System.out.println(strings);
    }
}

private static String difference(String s1, String s2) {
    String diff = "";
    String[] strList1 = s1.split(" ");
    String[] strList2 = s2.split(" ");

    List<String> list1 = Arrays.asList(strList1);
    List<String> list2 = Arrays.asList(strList2);

    // Prepare a union
    List<String> union = new ArrayList<>(list1);
    union.addAll(list2);

    // Prepare an intersection
    List<String> intersection = new ArrayList<>(list1);
    intersection.retainAll(list2);

    // Subtract the intersection from the union
    union.removeAll(intersection);

    for (String s : union) {
        //System.out.println(s);
        diff += s;
    }
    return diff;
}

private static LinkedHashSet<LinkedHashSet<String>> powerset(String[] set) {

    //create the empty power set
    LinkedHashSet<LinkedHashSet<String>> power = new LinkedHashSet<>();

    //get the number of elements in the set
    int elements = set.length;

    //the number of members of a power set is 2^n
    int powerElements = (int) Math.pow(2,elements);

    //run a binary counter for the number of power elements
    for (int i = 0; i < powerElements; i++) {

        //convert the binary number to a string containing n digits
        String binary = intToBinary(i, elements);

        //create a new set
        LinkedHashSet<String> innerSet = new LinkedHashSet<String>();

        //convert each digit in the current binary number to the corresponding element
        //in the given set
        for (int j = 0; j < binary.length(); j++) {
            if (binary.charAt(j) == '1')
                innerSet.add(set[j]);
        }

        //add the new set to the power set
        power.add(innerSet);

    }
    return power;
}
/**
 * Converts the given integer to a String representing a binary number
 * with the specified number of digits
 * For example when using 4 digits the binary 1 is 0001
 * @param binary int
 * @param digits int
 * @return String
 */
private static String intToBinary(int binary, int digits) {

    String temp = Integer.toBinaryString(binary);
    int foundDigits = temp.length();
    String returner = temp;
    for (int i = foundDigits; i < digits; i++) {
        returner = "0" + returner;
    }
    return returner;
} 

Output

[b, c, d]
[e, a, b]
[c, a]
[b, d, c]
[b, d, c]
a b c d e 
a b c d 
e
[[], [e], [d], [d, e], [c], [c, e], [c, d], [c, d, e], [b], [b, e], [b, d], [b, d, e], [b, c], [b, c, e], [b, c, d], [b, c, d, e], [a], [a, e], [a, d], [a, d, e], [a, c], [a, c, e], [a, c, d], [a, c, d, e], [a, b], [a, b, e], [a, b, d], [a, b, d, e], [a, b, c], [a, b, c, e], [a, b, c, d], [a, b, c, d, e]]
[]
[e]
[d]
[d, e]
[c]
[c, e]
[c, d]
[c, d, e]
[b]
[b, e]
[b, d]
[b, d, e]
[b, c]
[b, c, e]
[b, c, d]
[b, c, d, e]
[a]
[a, e]
[a, d]
[a, d, e]
[a, c]
[a, c, e]
[a, c, d]
[a, c, d, e]
[a, b]
[a, b, e]
[a, b, d]
[a, b, d, e]
[a, b, c]
[a, b, c, e]
[a, b, c, d]
[a, b, c, d, e]

To help finding flaws in your code, it does help to use Generics all through the code. An IDE like Eclipse will warn you, when you forget to use Generics.

Taking your powerset method and using generics yields the following code:

private static Set<Set<String>> powerset(String[] set) {

    // create the empty power set
    Set<Set<String>> power = new LinkedHashSet<>();

    // get the number of elements in the set
    int elements = set.length;

    // the number of members of a power set is 2^n
    int powerElements = (int) Math.pow(2, elements);

    // run a binary counter for the number of power elements
    for (int i = 0; i < powerElements; i++) {

        // convert the binary number to a string containing n digits
        String binary = intToBinary(i, elements);

        // create a new set
        Set<String> innerSet = new LinkedHashSet<String>();

        // convert each digit in the current binary number to the corresponding element
        // in the given set
        for (int j = 0; j < binary.length(); j++) {
            if (binary.charAt(j) == '1')
                innerSet.add(set[j]);
        }

        // add the new set to the power set
        power.add(innerSet);

    }
    return power;
}

So the actual object you are returning is a Set of Sets. As you did not use Generics you can trick yourself (and the compiler) to believe you are using a Set. At runtime it is still a Set> so the ClassCastException is thrown.

The correct method to print your results will be as follows:

    for (Set<String> setOfStrings : myPowerSet) {
        System.out.println(setOfStrings);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM