【问题标题】:ClassCastException from LinkedHashSet to String从 LinkedHashSet 到 String 的 ClassCastException
【发布时间】:2016-03-15 20:20:58
【问题描述】:

我想从 LinkedHashSet 中获取字符串数组,但我在尝试在 foreach 循环中打印我的值的地方得到 ClassCastException。

我知道 powerset 方法有问题,但是当我尝试通过在方法中添加 LinkedHashSet 来修复它时,我失败了。

我相信有一种方法可以让字符串脱离对象。最后的想法是将它写在文件中,而不是使用正则表达式,但它似乎很奇特......

跟踪: 线程“主”java.lang.ClassCastException 中的异常:java.util.LinkedHashSet 无法转换为 [Ljava.lang.String; 在 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;
       } 
}

【问题讨论】:

  • 首先使用LinkedHashSet&lt;String&gt; 而不是LinkedHashSet(它可能不会直接解决您的问题,但会更安全)。
  • 但这就是问题所在。他正在构建LinkedHashSet&lt;LinkedHashSet&lt;String&gt;&gt;,然后将其视为LinkedHashSet&lt;String[]&gt;。它不是。
  • @EugeneShymko 你应该阅读Generics tutorial,尤其是关于“原始类型”的部分。
  • 如果myPowerSetLinkedHashSet&lt;LinkedHashSet&lt;String&gt;&gt; 类型,那么sArr 需要是ArrayList&lt;LinkedHashSet&lt;String&gt; 类型。 (虽然您实际上不需要将集合复制到列表中进行迭代,但您可以直接在增强的 for 循环声明中使用myPowerSet)。
  • 并使用-Xlint:rawtypes编译您的代码。

标签: java arrays exception linkedhashset


【解决方案1】:

为了帮助发现代码中的缺陷,在整个代码中使用泛型确实会有所帮助。当您忘记使用泛型时,像 Eclipse 这样的 IDE 会警告您。

采用您的 powerset 方法并使用泛型会产生以下代码:

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;
}

因此,您返回的实际对象是一组集合。 由于您没有使用泛型,您可以欺骗自己(和编译器)相信您正在使用 Set。在运行时它仍然是一个 Set> 所以抛出 ClassCastException。

打印结果的正确方法如下:

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

【讨论】:

  • toString() 在“打印结果的方法”中是多余的。
  • 你是对的,我更新了我的答案。有趣的是,原始发布者可能会留下他的旧打印代码,并且只需使用正确的泛型它就可以工作。
  • 如果我想将纯字符串放入 ArrayList str 怎么办?我尝试使用 str.add(setOfStrings.toString());但出现编译错误 ArrayList 类型中的方法 add(String[]) 不适用于参数 (String)
  • @EugeneShymko 请-在上面的 cmets 中接受我的建议-去阅读generics tutorial。它解释了这样的问题。
  • 编译器的信息其实很清楚:如果你有一个 List 你可以添加新的 String 数组。但是当您调用 list.add(xyz.toString()) 时,您正在尝试添加单个字符串而不是字符串数组。
【解决方案2】:

TL;DR

使用泛型


LinkedHashSet myPowerSet;

应该是

LinkedHashSet<LinkedHashSet<String>> myPowerSet;

对您的代码进行必要的更改,答案就会立即出现在您的眼前。

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

实际上并不采用String[],而是采用String,因为它在myPowerSet 中使用的类型,因此以下内容也将更改

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

完整代码

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;
} 

输出

[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]

【讨论】:

  • 不是LinkedHashSet&lt;String&gt; myPowerSet。仔细查看powerset 方法中添加到power 的内容。
  • 你不明白 power set 是什么。
  • 恐怕这不再是幂集了,因为输出是 [e, d, c, b, a] 而不是 [[], [e], [d], [d, e], [c], [c, e] ...
  • @EugeneShymko 刚刚改了
  • @YassinHajaj 如果您不了解代码的含义,我可以建议您不要更改代码的语义:) 您对该方法所需要做的就是添加泛型.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多