Безопасность с точки зрения типов Дженериков Java, предупреждающая с рекурсивным Hashmap

Я использую рекурсивное дерево hashmaps, конкретно карта Hashmap, где Объект является ссылкой на другой Hashmap и так далее. Это будет роздано рекурсивный алгоритм:

foo(String filename, Hashmap<String, Object> map)
{
    //some stuff here
    for (Entry<String, Object> entry : map.entrySet()) 
    {
       //type warning that must be suppressed
       foo(entry.getKey(), (HashMap<String, Object>)entry.getValue());
    }
}

Я знаю наверняка Object имеет тип Hashmap<String, Object> но раздражены это, я должен подавить использование предупреждения @SuppressWarnings("unchecked").

Я буду удовлетворен решением, которое делает любого a assert(/*entry.getValue() is of type HashMap<String, Object>*/) или выдает исключение, когда это не. Я спустился по маршруту Дженериков для безопасности типов компиляции и если я подавляю предупреждение затем, что это побеждает цель.

Спасибо за Ваши комментарии, ksb

5
задан GC. 14 March 2010 в 21:13
поделиться

3 ответа

Это возможно при использовании общего метода с переменной рекурсивного типа. Попробуйте следующее:

public <T extends Map<String, T>> void foo(String filename, T map) {
    //some stuff here
    for (Map.Entry<String, T> entry : map.entrySet())  {
        foo(entry.getKey(), entry.getValue());
    }
}

Должно компилироваться нормально без предупреждений.

Однако, если у вас есть контроль над картой, и вы можете заменить свой собственный класс, возможно, будет более читабельным сделать класс Node (для меня это выглядит как дерево), который содержит Map вместо этого. Что-то вроде:

public class Node {
    private Map<String, Node> children;

    ...
    // accessor methods to retrieve children ...
}

И пусть foo принимает Node в качестве второго аргумента. Просто предложение.

5
ответ дан 13 December 2019 в 19:24
поделиться

Вы можете использовать этот класс вместо HashMap:

public class RecursiveHashMap extends HashMap<String,RecursiveHashMap>
{
}
5
ответ дан 13 December 2019 в 19:24
поделиться

Ваша структура данных выглядит так, как будто вы хотите представить с ее помощью деревья файлов (имен файлов). Я бы не рекомендовал делать это с HashMap в качестве типа узла.

Я бы предложил использовать составной шаблон (см. википедию), упрощенный код:

abstract class Node
{
  String filename;
  Node( String filename ) { this.filename = filename; }
  abstract foo();
}

class FileNode implements Node
{
  FileNode( String filename ) { super(filename); }
  foo() { ... }
}

class DirectoryNode implements Node 
{
  Set<Node> children;
  DirectoryNode( String filename, Set<Node> children )
  {
    super(filename);
    this.children = children;
  }
  foo()
  {
    for ( Node child : children ) child.foo();
  }
}

Используемая вами HashMap сводится к набору, отображаемому в DirectoryNode.

1
ответ дан 13 December 2019 в 19:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: