JAVA: First off, Thanks so much for taking the time to look at my question; your help is EXTREMELY appreciated!
So, the problem is i have a Vector of Objects in Java and each object has a name(String). But, i have tons of objects that are repeated, and the ones that are repeated are always directly after the Object they repeat. Also the number of repeats ranges from 1-10(So frustrating) its completely random.
How would i go about deleting the repeats, I thought about comparing each objects name with the next in the vector and deleting all of the ones that match but that gave me tons of problems. Thank you SO much for your help in advance!
-Dylan
EDIT: Just to make sure you understand the kind of repetition i'm talking about ive added this.
Vector
---Object1(String name = "hi") --> Remove This one.
---Object2(String name = "hi")
---Object3(string name = "bob")
End Vector
Edit 2: add Code
public class Vector
{
public static void main(String args[])
{
Person person1 = new Person("jane");
Person person2 = new Person("jane");
Person person3 = new Person("bob");
Person person4 = new Person("shelly");
Vector<Person> vectorObject = new Vector<Person>
vectorObject.add(person1);
vectorObject.add(person2);
vectorObject.add(person3);
vectorObject.add(person4);
}
}
class Person
{
String name = null;
String bDay = null;
String color = null;
public Person(String name)
{
this.name = name;
}
}
It seems you should use a different data structure.
You may want to use a Set instead of a Vector. Sets do not contain duplicate elements. You've to override equals(Object) method.
Or use a Map with the name property as key value and store the corresponding Person object as value.
In both cases you prevent duplicates rather then deleting them afterwards.
Person person1 = new Person("jane");
Person person2 = new Person("jane");
Person person3 = new Person("bob");
Person person4 = new Person("shelly");
Map<String, Person> nameToPerson = new HashMap<>();
nameToPerson.add(person1.name, person1);
nameToPerson.add(person2.name, person2);
nameToPerson.add(person3.name, person3);
nameToPerson.add(person4.name, person4);
Collection<Person> noDuplicatesHere = map.values();
Well, I don't know which language are you using, so I will give you an algorithm in JavaScript:
var newvector=new Array();
var lastName;
for(var i=0;i<vector.length;i++){
if(!lastName || vector[i].name!=lastName){
lastName=vector[i].name;
newvector.push(vector[i]);
}
}
The problem is that this way a new vector is created, and if the original one is huge maybe you will have memory problems.
Here is your first problem:
class Person
{
String name = null;
String bDay = null;
String color = null;
public Person(String name)
{
name = this.name;
}
}
it should be:
class Person
{
String name = null;
String bDay = null;
String color = null;
public Person(String name)
{
this.name = name;
}
}
Here is more info on the this keyword:
http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
Your second problem is: I'm guessing you are trying to create a Vector, java.util.Vector to be exact. If you create a new instance of Vector inside of a class called vector, it will create a new instance of itself, not of java.util.Vector. You can either rename the class or you can just do:
java.util.Vector<Person> vector = new java.util.Vector<Person>();
if you want to compare 2 string values use:
String name = "John";
String name2 = "Joe";
if(name.equalsIgnoreCase(name2))
System.out.println("They match!");
You can also just use equals() if you want an exact match.
Hope this helped!
Related
I need to implement a method which should take an array of persons, basically public String oldest (Person [] persons), and return the oldest one. The persons which will be inputed are the following:
new Person("Augusta Ada King, grevinna av Lovelace", 1815),
new Person("Muhammad ibn Musa al-Khwarizmi", 780),
new Person("Alan Turing", 1912),
new Person("Grace Hopper", 1906)
Below you can find my class Called Person. I've tried all different solutions with basic for-loop but I feel really lost and would appreciate any input or recommendation how I should write the method to find the oldest person.
class Person {
String name;
int yearOfBirth;
public Person(String name, int yearOfBirth) {
this.name = name;
this.yearOfBirth = yearOfBirth;
}
public int getAge() {
return getAge(java.time.LocalDate.now().getYear());
}
public int getAge(int year) {
return year - yearOfBirth;
}
#Override
public String toString() {
return String.format("%s %d", name, yearOfBirth);
}
public String oldest(Person [] persons){
}
You can try this:
Person oldest = Arrays.stream(persons).max(Comparator.comparing(Person::getAge)).get();
You need to iterate over your persons array and check which yearOfBirth is greater. You can implement your method like below:
public String oldest(Person[] persons) {
Person oldestPerson = persons[0];
for (Person person : persons) {
if (person.getYearOfBirth() < oldestPerson.getYearOfBirth()) {
oldestPerson = person;
}
}
return oldestPerson.getName();
}
This method should be static since it has nothing to do with an instance, and otherwise you have to call the method from an instance, which you probably don't want to do
Want should happen if you have more then one (oldest) person with the same age?
Why should the return be only the name and not a Person?
public static String oldest(Person[] persons) {
if (persons == null){
throw new NullPointerException("persons == null");
}
if (persons.length == 0) {
return null; //or throw same Exception depending on your handling
}
Person oldestPerson = persons[0];
for (Person person : persons) {
if (person.yearOfBirth < oldestPerson.yearOfBirth) {
oldestPerson = person;
}
}
return oldestPerson.name;
}
Since there could be the possibility of more than one oldest person I would do it as follows:
Here is some data with two oldest people (sort of)
Person[] people = {
new Person("Augusta Ada King, grevinna av Lovelace",
1815),
new Person("Muhammad ibn Musa al-Khwarizmi", 780),
new Person("Another oldest person", 780),
new Person("Alan Turing", 1912),
new Person("Grace Hopper", 1906) };
String s = Person.oldest(people);
System.out.println(s);
prints
Muhammad ibn Musa al-Khwarizmi
Another oldest person
first I would make the method static since it doesn't rely on instance fields but an array of instances.
I would use a map to facilitate holding the the names of the people using their age as the key. Use the Map.merge method to populate the map and handle duplicate ages
Now iterate thru the names and as you do so:
find the oldest age.
store the name as the value for that age.
if another is found of the same age, concatenate the name with a newline(\n) and update the current map value.
when finished, return the value for the computed oldest individual(s).
public static String oldest(Person[] persons) {
int oldest = 0;
Map<Integer, String> ages = new HashMap<>();
for (Person p : persons) {
int age = p.getAge();
oldest = Math.max(oldest, age);
ages.merge(age, p.name, (last, current)- > last + "\n" + current);
}
return ages.get(oldest);
}
In case you would rather return a List of names your method can look like this. The main differences are:
return a List<String> which contains the names
using a Map<Integer, List<String>> to contain the people based on age.
computeIfAbsent to initialize the maps value for that age one time and then add the name to the list.
public static List<String> oldest(Person[] persons) {
int oldest = 0;
Map<Integer, List<String>> ages = new HashMap<>();
for (Person p : persons) {
int age = p.getAge();
oldest = Math.max(oldest, age);
ages.computeIfAbsent(age, v->new ArrayList<>()).add(p.name);
}
return ages.get(oldest);
}
It would then be called like so
List<String> list = Person.oldest(people);
list.foreach(System.out::println); // to print - same as before.
My final recommendation is that you use Lists over Arrays as they have advantages, the main on (imho) being that they grow dynamically as you add more items.
I am working on a group generator and currently I am making an ArrayList from this txt file.
So that, the ArrayList is in the form of [PedroA, Brazil, Male, 10G, Saadia...]
I want to shuffle 4 elements at a time, to randomize this arraylist.
I am storing the info in
ArrayList<String> studentInfo = info.readEachWord(className);
This is very hard to do. It's possible, of course, but difficult.
It is being made difficult because what you want to do is bizarre.
The normal way to do this would be to:
Make a class representing a single entry, let's call it class Person.
Read this data by parsing each line into a single Person instance, and add them all to a list.
Just call Collections.shuffle(list); to shuffle them.
If we have the above, we could do what you want, by then converting your List<Person> back into a List<String>. In many ways this is the simplest way to do the task you ask for, but then you start wondering why you want this data in the form of a list of strings in the first place.
enum Gender {
MALE, FEMALE, OTHER;
public static Gender parse(String in) {
switch (in.toLowerCase()) {
case "male": return MALE;
case "female": return FEMALE;
default: return OTHER;
}
}
class Person {
String name;
String location;
Gender gender;
[some type that properly represents whatever 10G and 10W means];
public static Person readLine(String line) {
String[] parts = line.split("\\s+", 4);
Person p = new Person();
p.name = parts[0];
p.location = parts[1];
p.gender = Gender.parse(parts[2]);
...;
return p;
}
}
you get the idea.
Suppose I have a class Employee :
class Employee {
Employee(String name, int age)
{
this.name = name ;
this.age = age;
}
String name ;
int age;
}
Now Create a List of this like :
ArrayList<Employee> aa = new ArrayList<Employee>();
aa.add(new Employee("Nitish", 26));
aa.add(new Employee("Sh", 2));
aa.add(new Employee("S", 1));
Can i get Employee Object Where name value is "Nitish"? Without For loop
I guess your interviewer just doesn't want you to use for or while loops to find objects in an ArrayList, but you can actually find them "without loops".
First, you need to override equals and hashCode of Employee class:
#Override public boolean equals(Object obj) {
// ...
}
#Override public int hashCode() {
// ...
}
Now you can find your object with ArrayList.indexOf (uses equals to find match) by creating a dummy reference:
Employee target = new Employee("Nitish", 26);
int index = employees.indexOf(target);
It's kinda silly but I guess some interviewers want us to think outside-of-the-box. Even though under the hood it's using loops, but if my interviewer asks me the same question, instead of saying no you can't, I'd use this example because I want to try my best just not to use "loops" as asked, and explains how it works behind the scene. Then afterwards I'd briefly come up with other better solutions, and hope that works!
You can use a filtered stream:
Object[] array = aa
.stream()
.parallel()
.filter((emp) -> emp.name.equals("Nitish"))
.toArray();
if (array.length > 0) {
Employee employee = (Employee)array[0];
String name = employee.name;
int age = employee.age;
System.out.println("Found Employee with Name = " + name + " and Age = " + age);
} else {
System.out.println("Not Found");
}
Try this
Employee emp = aa.stream().filter(e->e.name.equals("Nitish")).findAny().orElse(null);
this version returns null if not found
ArrayList work on index based structure.to ADD,READ,GET value from array need to index of the specific index.
instead store data on ArrayList you can use Map.
Using key can be access value from Map.
Map<String, Employee> employeeMap = new HashMap<>();
employeeMap.put("Nitish", new Employee("Nitish", 26));
employeeMap.put("Sh", new Employee("Sh", 2));
employeeMap.put("S", new Employee("S", 1));
System.out.println(employeeMap.get("Nitish").getName());
System.out.println(employeeMap.get("Nitish").getAge());
I'm very new to Java and Android development.
I have a case where I need to populate an object with data from an XML document. Some of the node names in the XML are not standardised in any way, so I have created a HashMap where the key is the node name, and the value is the variable it needs to be assigned to.
In PHP the code would look something like (in basic terms):
$array = new Array("somenodename" => "firstname", "someothernodename" => "lastname");
$object = new Person();
$object->{$array['somenodename']} = "Whatever the XML node value was";
In Java I have gotten as far as:
From the object I need to populate:
public String firstname;
public String lastname;
public static Map getHashMap(){
Map<String, String> map = new HashMap<String, String>();
map.put("somenodename", "firstname");
map.put("someothernodename", "lastname");
return map;
}
From the class populating the object assuming the somenode and someothernode are dymanic:
Person person;
Map personMap = person.getHashMap();
if( personMap.containsKey("somenodename") ){
person.[personMap.get("somenodename")] = "James";
}
if( personMap.containsKey("someothernodename") ){
person.[personMap.get("someothernodename")] = "Bond";
}
Is there anyway of assigning a value to an class variable where the variable name is... variable?
It's called Reflection
Assume you want to call the method myMethod(String s) from Person:
Person p = new Person();
Class<Person> clazz = p.getClass();
Method m = clazz.getMethod("myMethod", String.class);
m.invoke(p, "my string argument");
I've created a Map with ten people's details, I want to then print out the names.
At the moment I have to print out each one individually, I want to have about 200 people so I wanted to know if it would be possible to print the names out in a loop.
(simplified code)
public class PersonDetails implements Serializable {
private String name;
private int age;
...
public PersonDetails(int Age, String Name) {
name = Name;
age = Age;
...
}
}
public class Test implements Serializable {
Map<String, PersonDetails> people = new TreeMap<String, PersonDetails>();
public Test() {
//10 people added
for(int x = 0; x<10; x++){
addPerson();
}
PersonDetails p0 = people.get("0");
String p0name = p0.getName();
System.out.println(p0name);
PersonDetails p1 = people.get("1");
String p1name = p1.getName();
System.out.println(p1name);
PersonDetails p2 = people.get("2");
String p2name = p2.getName();
System.out.println(p2name);
PersonDetails p3 = people.get("3");
String p3name = p3.getName();
System.out.println(p3name);
...
(I would like to loop this)
}
OUTPUT:
Connor
Phil
Nick
Mike
Sarah
Tom
Jenny
Eric
Jerry
Dave
Is it possible to have the same output and loop these outputs? I have tried an ArrayLists but I can't get it to work with this problem, and I am not sure if it is possible.
Thanks
Yes it is:
for (PersonDetails p: people.keySet())
{
System.out.println(p.getName());
}
You should specify the types of the people member variable when declaring and initializing. I think the key is a String, given get("0"), so:
Map<String, PersonDetails> people = new TreeMap<String, PersonDetails>();
To use an ArrayList:
List<PersonDetails> people = new ArrayList<PersonDetails>();
people.add(new PersonDetails(42, "Martin"));
for (PersonDetails p: people)
{
System.out.println(p.getName());
}
Map<String, PersonDetails> people = new HashMap<String, PersonDetails>();
// add to the Map this way
people.put(person.getName(), person);
for (Person p : people.keySet()) {
System.out.print(String.format("%s ", p.getName());
}
System.out.println();
You get the idea.