В принципе, ==
сравнивает, если два объекта имеют одну и ту же ссылку в куче, поэтому, если две ссылки не связаны с одним и тем же объектом, это сравнение будет ложным.
equals()
- метод унаследованный от класса Object
. Этот метод по умолчанию сравнивает, если два объекта имеют одинаковое рефери. Это означает:
object1.equals(object2)
& lt; => object1 == object2
Однако, если вы хотите установить равенство между двумя объектами того же класса, вы должны переопределить этот метод. Также очень важно переопределить метод hashCode()
, если вы переопределили equals()
.
Реализация hashCode()
при установлении равенства является частью Контракта объектов Java. Если вы работаете с коллекциями, а вы не реализовали hashCode()
, могут возникнуть Strange Bad Things:
HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));
null
будет напечатано после выполнения предыдущего кода, если вы еще не реализовали hashCode()
.
Хорошо, конечно, можно всегда извлекать элементы верхнего уровня (является ли это гранулярностью, которую Вы хотите, ваше дело). В C# Вы использовали бы класс XmlDocument. Например, если Ваш XML-файл выглядел примерно так:
<Document>
<Piece>
Some text
</Piece>
<Piece>
Some other text
</Piece>
</Document>
затем Вы использовали бы код как это для извлечения всех Частей:
XmlDocument doc = new XmlDocument();
doc.Load("<path to xml file>");
XmlNodeList nl = doc.GetElementsByTagName("Piece");
foreach (XmlNode n in nl)
{
// Do something with each Piece node
}
После того как у Вас есть узлы, можно сделать что-то с ними в коде, или можно передать весь текст узла к его собственному XML-документу и действовать на это, как будто это была независимая часть XML (включая сохранение его назад к диску, и т.д.).
Парсинг XML-документов с помощью DOM не масштабируется.
Этот сценарий Groovy использует StAX (Потоковый API для XML) для разделения XML-документа между элементами верхнего уровня (который совместно использует тот же QName как первый ребенок корневого документа). Это довольно быстро, обрабатывает произвольные большие документы и очень полезно, когда Вы хотите разделить большой пакетный файл на мелкие кусочки.
Требует Groovy на Java 6 или StAX API и реализации, такой как Woodstox в ПУТИ К КЛАССУ
import javax.xml.stream.*
pieces = 5
input = "input.xml"
output = "output_%04d.xml"
eventFactory = XMLEventFactory.newInstance()
fileNumber = elementCount = 0
def createEventReader() {
reader = XMLInputFactory.newInstance().createXMLEventReader(new FileInputStream(input))
start = reader.next()
root = reader.nextTag()
firstChild = reader.nextTag()
return reader
}
def createNextEventWriter () {
println "Writing to '${filename = String.format(output, ++fileNumber)}'"
writer = XMLOutputFactory.newInstance().createXMLEventWriter(new FileOutputStream(filename), start.characterEncodingScheme)
writer.add(start)
writer.add(root)
return writer
}
elements = createEventReader().findAll { it.startElement && it.name == firstChild.name }.size()
println "Splitting ${elements} <${firstChild.name.localPart}> elements into ${pieces} pieces"
chunkSize = elements / pieces
writer = createNextEventWriter()
writer.add(firstChild)
createEventReader().each {
if (it.startElement && it.name == firstChild.name) {
if (++elementCount > chunkSize) {
writer.add(eventFactory.createEndDocument())
writer.flush()
writer = createNextEventWriter()
elementCount = 0
}
}
writer.add(it)
}
writer.flush()
Это - больше комментария, чем ответ, но не было бы:
XmlDocument doc = new XmlDocument();
doc.Load("path");
Считать весь файл сразу? Просто мысль, я должен поднять вопрос с тех пор от вида вопроса Thomas, он обеспокоен чтением больших файлов и хочет сломать процесс..
Как DannySmurf касается здесь, это - все о структуре xml документа.
Если Вы только два огромных "высокоуровневых" тега, будет чрезвычайно трудно смочь разделить его способом, который позволяет и объединить его назад вместе и считать его часть частью как допустимый xml.
Учитывая документ с большим количеством отдельных частей как те в примере DannySmurfs, это должно быть довольно легко.
Некоторый грубый код в Псевдо C#:
int nrOfPieces = 5;
XmlDocument xmlOriginal = some input parameter..
// construct the list we need, and fill it with XmlDocuments..
var xmlList = new List<XmlDocument>();
for (int i = 0; i < nrOfPieces ; i++)
{
var xmlDoc = new XmlDocument();
xmlDoc.ChildNodes.Add(new XmlNode(xmlOriginal.FistNode.Name));
xmlList.Add(xmlDoc);
}
var nodeList = xmlOriginal.GetElementsByTagName("Piece")M
// Copy the nodes from the original into the pieces..
for (int i = 0; i < nodeList .Count; i++)
{
var xmlDoc = xmlList[i % nrOfPieces];
var nodeToCopy = nodeList[i].Clone();
xmlDoc.FirstNode.ChildNodes.Add(nodeToCopy);
}
Это должно дать Вам n документы с корректным xml и возможностью объединить их назад вместе.
Но снова, это зависит от XML-файла.
Это считало бы весь файл сразу. По моему опыту, тем не менее, если Вы просто читаете файл, делая некоторую обработку (т.е. разбивание это) и затем продвигаетесь с Вашей работой, XmlDocument собирается пройти, это, создают/читают/собирают цикл так быстро, что это, вероятно, не будет иметь значения.
Конечно, это зависит от того, каков "большой" файл. Если это будет XML-файл на 30 МБ (который я считал бы большим для XML-файла), то это, вероятно, не будет иметь никакого значения. Если это будет XML-файл на 500 МБ, то использование XmlDocument станет чрезвычайно проблематичным в системах без существенного количества RAM (в этом случае, однако, я утверждал бы, что время для ручного выбора через файл с XmlReader будет более значительным препятствием).
Не уверенный, какую обработку Вы делаете, но для очень большого XML, я всегда был поклонником основанной на событии обработки. Возможно, это - мое образование Java, но мне действительно нравится SAX. Необходимо сделать собственное управление состоянием, но после того как Вы заканчиваете это, это - очень эффективный способ парсинга XML.
Если у Вас не полностью аллергия на Perl, то XML:: Ветка идет с инструментом, названным xml_split, который может разделить документ, произведя правильно построенный раздел XML. Можно разделить на уровне дерева размером или на выражении XPath.
Я собираюсь пойти с youphoric на этом. Для очень больших файлов SAX (или любой другой синтаксический анализатор потоковой передачи) будет большой справкой в обработке. Используя DOM можно собрать просто высокоуровневые узлы, но все еще необходимо проанализировать весь документ, чтобы сделать это... использование синтаксического анализатора потоковой передачи и основанная на событии обработка позволяют Вам "пропустить" узлы, которыми Вы не интересуетесь; делает обработку быстрее.
Похоже, что Вы работаете с C# и.NET 3.5. Я столкнулся с некоторыми сообщениями, которые предлагают использовать тип урожая алгоритма на потоке файла с XmlReader.
Вот пара сообщений в блоге для запущения Вас вниз путь:
Я сделал видео на YouTube, показывающее , как разделить файлы XML с помощью foxe (бесплатный XML-редактор от Firstobject ), использующий лишь небольшой объем памяти независимо от размера входных и выходных файлов.
Использование памяти для этого считывателя XML CMarkup (анализатор запроса) и Решение для записи XML зависит от размера вложенных документов, которые по отдельности передаются из входного файла в выходные файлы, или от минимального размера блока 16 КБ.
split() { CMarkup xmlInput, xmlOutput; xmlInput.Open( "50MB.xml", MDF_READFILE ); int nObjectCount = 0, nFileCount = 0; while ( xmlInput.FindElem("//ACT") ) { if ( nObjectCount == 0 ) { ++nFileCount; xmlOutput.Open( "piece" + nFileCount + ".xml", MDF_WRITEFILE ); xmlOutput.AddElem( "root" ); xmlOutput.IntoElem(); } xmlOutput.AddSubDoc( xmlInput.GetSubDoc() ); ++nObjectCount; if ( nObjectCount == 5 ) { xmlOutput.Close(); nObjectCount = 0; } } if ( nObjectCount ) xmlOutput.Close(); xmlInput.Close(); return nFileCount; }