package stexfires.core;

import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * @author Mathias Kalb
 * @since 0.1
 */
public final class Field implements Serializable {

    private static final long serialVersionUID = 1L;

    private final int index;
    private final boolean last;
    private final String value;

    public Field(int index, boolean last, String value) {
        if (index < Fields.FIRST_FIELD_INDEX) {
            throw new IllegalArgumentException("Illegal index! index=" + index);
        }
        this.index = index;
        this.last = last;
        this.value = value;
    }

    public int getIndex() {
        return index;
    }

    public boolean isFirst() {
        return index == Fields.FIRST_FIELD_INDEX;
    }

    public boolean isLast() {
        return last;
    }

    public String getValue() {
        return value;
    }

    public String getValueOrElse(String other) {
        return value != null ? value : other;
    }

    public Optional<String> getValueAsOptional() {
        return Optional.ofNullable(value);
    }

    public boolean valueEquals(String other) {
        return Objects.equals(value, other);
    }

    public boolean valueIsNull() {
        return value == null;
    }

    public boolean valueIsEmpty() {
        return value != null && value.isEmpty();
    }

    public boolean valueIsNullOrEmpty() {
        return value == null || value.isEmpty();
    }

    public int length() {
        return value != null ? value.length() : 0;
    }

    public Stream<String> stream() {
        if (value == null) {
            return Stream.empty();
        }
        return Stream.of(value);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Field that = (Field) o;

        if (index != that.index) return false;
        //noinspection SimplifiableIfStatement
        if (last != that.last) return false;
        return value != null ? value.equals(that.value) : that.value == null;

    }

    @Override
    public int hashCode() {
        int result = index;
        result = 31 * result + (last ? 1 : 0);
        result = 31 * result + (value != null ? value.hashCode() : 1); // Replaced 0 with 1
        return result;
    }

    @Override
    public String toString() {
        return "Field{" + index + ", " + last + ", " + (value != null ? "'" + value + "'" : "null") + "}";
    }

}

@@ -375,24 +375,94 @@
 ing value;%0A%0A
+    private final int hashCode;%0A%0A    @SuppressWarnings(%22MagicNumber%22)%0A
     public F
@@ -723,24 +723,248 @@
 lue = value;
+%0A%0A        // Calculate hashCode%0A        int calcHashCode = 31 * index + (last ? 1 : 0);%0A        if (value != null) %7B%0A            calcHashCode = 31 * calcHashCode + value.hashCode();%0A        %7D%0A        hashCode = calcHashCode;
 %0A    %7D%0A%0A    
@@ -2095,16 +2095,28 @@
 is == o)
+%0A           
  return 
@@ -2173,16 +2173,28 @@
 Class())
+%0A           
  return 
@@ -2215,20 +2215,21 @@
   Field 
-that
+field
  = (Fiel
@@ -2234,25 +2234,24 @@
 eld) o;%0A
-%0A
         
 if (inde
@@ -2246,102 +2246,55 @@
     
-if (
+return 
 index 
-!= that
+== field
 .index
-) return false;%0A        //noinspection SimplifiableIfStatement%0A
+ &&%0A        
         
 if (
@@ -2293,361 +2293,154 @@
     
-if (
 last 
-!= that.last) return false;%0A        return value != null ? value.equals(that.value) : that.value == null;%0A%0A    %7D%0A%0A    @Override%0A    public int hashCode() %7B%0A        int result = index;%0A        result = 31 * result + (last ? 1 : 0);%0A        result = 31 * result + (value != null ? value.hashCode() : 1); // Replaced 0 with 1%0A        return result
+== field.last &&%0A                Objects.equals(value, field.value);%0A    %7D%0A%0A    @Override%0A    public int hashCode() %7B%0A        return hashCode
 ;%0A  

Change equals() and hashCode()